4

I made a little slider to loop 3 images, I want every image stop 3 seconds, then fadeOut and fadeIn the next one, but the problem is :
the first one can stay 3 seconds, but once it begins to loop, it won't stop 3 seconds again, the image change immediately, why it can't keep the 3 seconds to stay?
Here is the Demo

var i = 0;
var name = ['Cat', 'Dog', 'Duck'];

function next() {
  if (i > 1) {
    i = 0;
  } else {
    i++;
  };
  $('#loop').fadeOut(1000, function() {
    $(this).css('background', 'url("' + i + '.png")').fadeIn(1000);
    $('h1').html(name[i]);
  });
};
setInterval(next, 3000);
#loop {
  width: 300px;
  height: 300px;
  background: url('0.png');
}
h1 {
  padding-top: 310px;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loop">
  <h1>Cat</h1>
</div>
chirag
  • 1,761
  • 1
  • 17
  • 33
Jiang Lan
  • 171
  • 1
  • 12
  • I tried your demo on Firefox and it works perfectly. In which browser you have problems? – AwesomeGuy Oct 16 '16 at 09:58
  • I feel that after the first image, every image dosen't stay 3 seconds – Jiang Lan Oct 16 '16 at 10:00
  • 1
    Ah I see, you see, image will be present for 3 seconds from the beggining of fadeIn(), so fadeIn and fadeOut times are calculated in those 3 seconds. And as your transitions last for 1 second, 1 second only is left for the image to stay. Increase your interval time to 5 seconds, and before setInterval put setTimeout(next, 3000); – AwesomeGuy Oct 16 '16 at 10:03
  • I try your idea, add "setTimeout(next, 3000);" before "setInterval(next, 5000);", but the second image stay less then 1 second, then the other is good, why the second one can not stay 3 seconds? – Jiang Lan Oct 16 '16 at 10:12
  • Your best bet is to use promise: http://stackoverflow.com/a/27660144/1414562 – A. Wolff Oct 16 '16 at 10:16

2 Answers2

3

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Loop</title>
    <style type="text/css">
        #loop{
            width: 300px;
            height: 300px;
            background: url('0.png');
        }
        h1{
            padding-top: 310px;
            text-align: center;
        }
    </style>
</head>
<body>
<div id="loop">
    <h1>Cat</h1>
</div>


<script src="https://code.jquery.com/jquery-3.0.0.min.js"
        integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0="
        crossorigin="anonymous">
</script>
<script>
    $(function (){
        var i = 0;
        var name = ['Cat', 'Dog', 'Duck'];

        var timerId = setTimeout(next, 3000);
        function next(){
            if (i > 1) {
                i = 0;
            }else{
                i++;
            };
            $('#loop').fadeOut(1000, function (){
                $(this).css('background', 'url("'+ i +'.png")').fadeIn(1000);
                $('h1').html(name[i]);
                timerId = setTimeout(next, 3000);
            });
        };

    });
</script>
</body>


</html>
  • I try your code, adding the setTimeout, but the images are not show in order, and the speed is even more faster, every image can't stay for 1 second, I don't know why? – Jiang Lan Oct 16 '16 at 10:21
  • I posted all the code, it respects the order i think 1. cat 2. dog 3. duck. Hope the edited version helps you – Alberto Delgado Roda Oct 16 '16 at 10:28
  • Yes, it works, this is the best solution based on my code, thanks, but one thing I don't inderstand, why this can work only add a var "setTimeout" and call it once again in the function, can you explain a little more, please? – Jiang Lan Oct 16 '16 at 10:38
  • Hello i recommend you the next article from John Resig (jQuery creator) http://ejohn.org/blog/how-javascript-timers-work/ – Alberto Delgado Roda Oct 16 '16 at 10:40
  • I see now, setTimeout execute a function one time after the delay, and put this delay into the function to reexcute itself, this is a pure art !! – Jiang Lan Oct 16 '16 at 11:51
1

You can use .queue(), .delay(), .promise(), recursion

$(function() {

var names = ['Cat', 'Dog', 'Duck'];

var images = ["http://placehold.it/300x300?text=Cat"
             , "http://placehold.it/300x300?text=Dog"
             , "http://placehold.it/300x300?text=Duck"]

function next() {
  return $("#loop")
    .queue("names", $.map(names, function(name, i) {
      return function(next) {
        $(this).css("background", "url(" + images[i] + ")")
        .find("h1").html(name).end()
        .fadeIn(1000, function() {
          $(this).delay(3000)
          .fadeOut(1000).promise().then(next)
        })
      }
    }))
    .dequeue("names").promise("names").then(next)
};

next();

})
#loop {
  width: 300px;
  height: 300px;
  background-repeat:no-repeat;
}
h1 {
  padding-top: 310px;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loop">
  <h1>Cat</h1>
</div>
guest271314
  • 1
  • 15
  • 104
  • 177