Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to continuously rotate children in a jQuery animation?

I have a div with class 'bannergroup' that contains multiple divs 'banneritem'. I want these items to rotate (fade in then fade out) in place of each other.

I can have several divs with the class bannergroup and each one should rotate separately.

Here is the HTML:

<div class="bannergroup">
  <div class="banneritem">Only visible one at a time</div>
  <div class="banneritem">Only visible one at a time</div>
  <div class="banneritem">Only visible one at a time</div>
  <div class="banneritem">Only visible one at a time</div>
</div>

<div class="bannergroup">
  <div class="banneritem">Only visible one at a time</div>
  <div class="banneritem">Only visible one at a time</div>
  <div class="banneritem">Only visible one at a time</div>
  <div class="banneritem">Only visible one at a time</div>
</div>

My Jquery looks like:

$('.banneritem').css('display', 'none');
$('.bannergroup').children('.banneritem').each(function( i ) {
  $(this).fadeIn().delay(4000).fadeOut();               
});

The problem: the each statement continues to run before the previous div completes. I want it to wait until the previous child is gone. Also, I need this to continuously run. After a single time it stops. I can put this into a function, but I am not sure how to know to call it again.

EDIT: There are not always 4 child items. Also one group may have a different number of children than the others, but they should both rotate in-sync. It is ok if one completes before the other and then just restarts itself.

like image 479
jpsnow72 Avatar asked Feb 18 '23 12:02

jpsnow72


2 Answers

I have answered this question multiple times before. This time I will try wrapping it in a jQuery plugin. The .rotate() function will apply the effect you want to the children of the matched elements, a fade in/out effect per children in a continuous animation.

$.fn.rotate = function(){
  return this.each(function() {

    /* Cache element's children */
    var $children = $(this).children();

    /* Current element to display */
    var position = -1;

    /* IIFE */
    !function loop() {

        /* Get next element's position.
         * Restarting from first children after the last one.
         */
        position = (position + 1) % $children.length;

        /* Fade element */
        $children.eq(position).fadeIn(1000).delay(1000).fadeOut(1000, loop);
    }();
  });
};

Usage:

$(function(){
  $(".banneritem").hide();
  $(".bannergroup").rotate();
});  

See it here.

like image 141
Alexander Avatar answered Feb 20 '23 04:02

Alexander


jsFiddle example

$('div.bannergroup').each(function () {
    $('div.banneritem', this).not(':first').hide();
    var thisDiv = this;
    setInterval(function () {
        var idx = $('div.banneritem', thisDiv).index($('div.banneritem', thisDiv).filter(':visible'));
        $('div.banneritem:eq(' + idx + ')', thisDiv).fadeOut(function () {
            idx++;
            if (idx == ($('div.banneritem', thisDiv).length)) idx = 0;
            $('div.banneritem', thisDiv).eq(idx).fadeIn();
        });
    }, 2000);
});
like image 23
j08691 Avatar answered Feb 20 '23 04:02

j08691