Search code examples
jqueryloopsfadecycle

Have inner div elements fade in/out on a loop while user hovers


I've tried numerous examples elsewhere here on Stackoverflow but with no luck, basically I have a simple div with a number of child elements which I want to fade in and out on a loop while the user hovers the article element. You can see where I've got to thus far here:

http://jsfiddle.net/rWXu7/

My HTML:

<article class="product">
<div class="offers">
    <div>Offer 1</div>
    <div style="display: none;">Offer 2</div>
    <div style="display: none;">Offer 3</div>
</div>

My JS:

    var tickerID;
$("article.product").hover(function(){

    var list=$(this).find('div.offers > div');

    (function repeatTicker() {
      list.each(function(index) {
        $(this).fadeIn('slow').delay(2000).fadeOut('slow');
      });
      tickerID = setTimeout(repeatTicker, 2000);
    } ());
},
// Rollout
function(){
    clearTimeout(tickerID);
});

My CSS:

article {
    background-color: red;
    padding: 20px;
}

As you can see at present the each loop initiates the fadeIn, Delay and fadeOut on all the elements at once whereas I want to 'cycle' through each element one at a time.

I get why this doesn't work as it is but I'm having a blond moment in working out how to best solve the problem.

I want to avoid using something like 'innerfade' as it seems overkill for a single fade in/out loop.

Any thoughts greatly appreciated. :)


Solution

  • DEMO: http://jsfiddle.net/rWXu7/5/

    var divs = $('div.offers > div'),
        interval, current = $(divs[0]);
    
    var cycle = function(){
        var prev = current;   
        current = current.next();
        if (current.length == 0){
             current = $(divs[0]);
        }    
        prev.fadeOut(function(){
            current.fadeIn(); 
        });
    }
    
    $('article').hover(function(){
       interval = window.setInterval(cycle, 1000);    
    }, function(){
        window.clearInterval(interval);
    });
    

    Later Edit: (supporting multiple products)

    DEMO: http://jsfiddle.net/rWXu7/10/

    var interval;
    
    var cycle = function(parent){   
        var currentIdx = parent.data('current') || 0, 
            prev = $(parent.find('div.offers > div').get(currentIdx));  
        current = prev.next();
        if (current.length == 0){
             current = $(parent.find('.offers > div').get(0));
             currentIdx = 0;
        }else{
             currentIdx++;   
        }
        prev.fadeOut(function(){
            current.fadeIn(); 
            parent.data('current', currentIdx)
        });
    }
    
    $('article').hover(function(e){
        interval = window.setInterval(function(){
            cycle($(e.currentTarget));
        }, 1000);    
    }, function(){
        window.clearInterval(interval);
    });