2

I'm trying to modify a solution already on here but to have a total of 7 divs that fade in/out using the same space on the page. And then loop back to the first div to start again.

I also need to have variable timings, i.e. div one stays visible for 5 seconds, div two stays visible for 3 second, div three for 4 seconds and so on as it depends how much content each has.

I just can't seem to be able to successfully add a third div that fades in after div two (red one).

Code I am trying to modify:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

    <script>
$(document).ready(function() {
   $('#one').delay(3000).fadeOut(100);
   $('#two').delay(3000).fadeIn(100);
 });
</script>

<style>
html, body {background-color: yellow}
#one {
  width: 300px;
  height: 300px;
  position: absolute;
  top: 5px;
  left: 5px;
  z-index: 200;
  background-color: #00f;
  cursor: pointer;
}

#two {
  width: 300px;
  height: 300px;
  position: absolute;
  top: 5px;
  left: 5px;
  z-index: 100;
  background-color: #f00;
  display: none;
}
</style>

<div id="one">Content for Div one to go here</div>
<div id="two">Content for Div two to go here</div>

Any help would be much appreciated. Thanks.

fsylothian
  • 91
  • 3
  • 9
  • Thanks for all the answers. All work great. I'm using Violetluna's answer simply because it's the easiest for me to follow. – fsylothian Mar 25 '16 at 14:49

4 Answers4

1

So, I am going to provide a few code snippets. The first one is only to point out the concept of callback functions in JQuery as well as recursive callbacks. Take a look at this script:

Primer Code

(function Recur(){
    $('#one').delay(3000).fadeOut(100,function(){
     $('#two').delay(3000).fadeIn(100,function(){
      $('#two').delay(3000).fadeOut(100,function(){
       $('#three').delay(3000).fadeIn(100,function(){
        $('#three').delay(3000).fadeOut(100,function(){
         $('#one').delay(3000).fadeIn(100, function(){
                Recur();
         })
        })
       });
      })
     });
   });
})();

We have a script with an Immediately Invoked Function Expression that is invoked on document load. After a div fades out, the next one fades in. Then after the #one div is loaded back up, the Recur() function is called again to start the loop. This gives a sort of slideshow effect.

Please see the fiddle: https://jsfiddle.net/n16bnm1L/1/

This doesn't really give you an option of variable timing or anything, and it gets more cumbersome as you add more elements to it, but it was just there as a little tutorial on the concepts for the next code I am providing:

Working Slideshow w/ Variable Times

What if you added a class to each element and performed the slideshow based on the indices of the element set?

var i = 0;
var length = $('.item').length;
var variableTime = 3000; //default time

(function Recur(){
    switch(i){
     case 0:
      variableTime = 5000;
      break;
     case 1: 
      variableTime = 3000;
      break;
     case 2:
      variableTime = 4000;
      break;
    }
   $('.item').eq(i++).delay(variableTime).fadeOut(1000,function(){
     if(i == length){
      i = 0;
     }
   $('.item').eq(i).fadeIn(1000,function(){
     Recur();
   });
 });
})();

Here is the fiddle for this: https://jsfiddle.net/n16bnm1L/2/

You can update the variable time switch statement as you add more div's. Just make sure for these div elements that you add the class item.

An Even Shorter Option!

What if you put the variable times in an array as the indices of the variable times and the elements will essentially match?

var i = 0;
var length = $('.item').length;
var variableTime = [5000,3000,4000];
(function Recur(){
  $('.item').eq(i).delay(variableTime[i++]).fadeOut(1000,function(){
    if(i == length){
     i = 0;
    }
    $('.item').eq(i).fadeIn(1000,function(){
     Recur();
    });
  });
})();

Here is a fiddle for this: https://jsfiddle.net/n16bnm1L/4/

A.Sharma
  • 2,771
  • 1
  • 11
  • 24
  • change your `switch-0-1-2` to array `[5000, 3000, 4000]`; – teran Mar 25 '16 at 14:20
  • do you have any links about recursions in JS ? in traditional languages endless-recursion leads to stackoverflow, what about JS ? – teran Mar 25 '16 at 14:27
  • This happens in JS too. But JQuery has built in safeguards to prevent this for specific functions. Take a look at this SO post: http://stackoverflow.com/questions/2705345/if-a-jquery-function-calls-itself-in-its-completion-callback-is-that-a-recursiv – A.Sharma Mar 25 '16 at 14:42
1

If you need a fadein/fadeout loop you can do something like this:

$(document).ready(function() {

loopbox();

function loopbox() {
    $('#one').fadeIn(100).delay(5000).fadeOut(100, function() {
      $('#two').fadeIn(100).delay(3000).fadeOut(100, function() {
        $('#three').fadeIn(100).delay(4000).fadeOut(100,function() {                                
        loopbox();
        });
      });
    });
  }
});

you can add as many divs you need in this callback function and choose different timing for each one.

Here's the jsfiddle

Violelune
  • 163
  • 1
  • 8
1

I believe that there exist more correct ways to solve this task, but as an option:

var cfg = { 
    "#one" : { delay : 1000, fade : 500},           
    "#two" : { delay : 2000, fade : 1000}, 
    "#three" : { delay : 3000, fade : 2000}
  };

var totalTime = 0;
$.each(cfg, function(k,v) { totalTime += v.delay + v.fade; });

loopDivs();
setInterval( loopDivs, totalTime);


function loopDivs(){  
  var d = 0;
  $.each(cfg, function(key, value){
    setTimeout( function(){ 
                    $(key).show()
                      .delay(value.delay)
                      .fadeOut(value.fade);
                  }, d);
    d += value.delay + value.fade;
  });
}

see full code here https://jsfiddle.net/57n3mL82/

teran
  • 3,214
  • 1
  • 21
  • 30
0

You have way too much redundancy going on here. You can do this pretty simply. Using classes in addition to ids

You can set styling classes so that there is one base style, and then whatever is different in each class can then be changed singularly instead of repetitive code.

The below also outlines how you can do this without having to worry about how many divs you want to fade in and out.

$(document).ready(function(){
  fadeNext($('#div-fader > div'), 0);
});

var fadeNext = function(that, index, fadeLast){
  
  //Set the newIndex to be passed back into this function
  //This will increment up to cycle through all of the divs
  //that are children of #div-fader
  //
  var newIndex = index+1;
  
  //If the Index is 0, then we know it is either the first time
  //around, or the fader is restarting
  //
  if(index == 0) {
    
    //the fadeLast flag, that is only passed to the function recursively
    //will tell the program that the last div (in this case the #six) is still
    //showing and needs to be hidden
    //
    if(fadeLast == true) {
      $($(that)[$(that).length-1]).fadeOut(100);
    }
    
    //Regardless, when the index is 0 always fade in the first div
    //
    $($(that)[index]).fadeIn(100);
  }
  
  //Otherwise, while the index is less than the length of $(that)
  //$(that) = #div-fader's div children
  //so length in this case will be 6 as there are 6 children of #div-fader
  //
  else if(index < $(that).length){
    $($(that)[index-1]).fadeOut(100);
    $($(that)[index]).fadeIn(100);
  }
  
  //Lastly, if we do not meet any of the above conditions, that means
  //we are at the last child of #div-fader and should go back to the start
  //
  else newIndex = 0;
  
  //the setTimeout will be where you set the timing in between each element
  //to call. So each div will fade-in and out at a rate of 1000ms
  //
  setTimeout(function(){
    
    //look at what is passed back into this function, remember the fadeLast flag?
    //that is passed here as true, because we are starting the cycle over
    //and the last div needs to be faded out
    //
    fadeNext(that, newIndex, true);
  }, 1000);
}
#div-fader > div {  
  width: 300px;
  height: 300px;
  position: absolute;
  top: 5px;
  left: 5px;
  display: none;
}

#one, #div-fader > div:nth-child(odd) {
  background-color: #00f;
  cursor: pointer;
}

#two, #div-fader > div:nth-child(even) {
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div-fader">
  <div id="one">Content for Div one to go here</div>
  <div id="two">Content for Div two to go here</div>
  <div id="three">Content for Div three to go here</div>
  <div id="four">Content for Div four to go here</div>
  <div id="five">Content for Div five to go here</div>
  <div id="six">Content for Div six to go here</div>
</div>
Adjit
  • 10,134
  • 12
  • 53
  • 98