Domanda

I created an image slider that ends on one image, but now I'd like to take it a step further and make it loop.

Here is my code in the head tag

<style>
#picOne, #picTwo, #picThree, #picFour, #picFive{
position:absolute;
display: none;
}

#pics {
width:500px;
height:332px;
}
</style>

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

<script type="text/javascript">
$(document).ready(function() { 
    $('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picFive').delay(20000).fadeIn(1500).delay(3500);
});
</script>

and here is where it is implemented in the body code

<div id="pics">
<center>
<img src="img/dolllay.jpg" width="500" height="332" id="picFive" />
<img src="img/dye.jpg" width="500" height="332" id="picTwo" />
<img src="img/dollsit.jpg" width="500" height="332" id="picThree" />
<img src="img/heirloom.jpg" width="500" height="332" id="picFour" />
<img src="img/heritage.jpg" width="500" height="332" id="picOne" />
</center>
</div>

Could I turn it into a function and then loop it? Can I get any guidance on that? Thank you very much

È stato utile?

Soluzione

Everyone's answering the question, but not solving the problem.

Sure, you can just put a loop wrapper around it (preferably one that doesn't terminate), but why not just program it right? Why have all the hardcoded times, and why not make it more robust?

Try rewriting your code like this. It makes it much easier to modify the pictures you loop through:

var pictures = ["picOne", "picTwo", "picThree", "picFour", "picFive"];
var index = 0;

var displayImage = function() {
    if (index == pictures.length) { return; }

    $("#" + pictures[index++]).fadeIn(1500).delay(3500).fadeOut(1500, displayImage);
};

displayImage();

Then, if you want to loop back, you simply tweak the displayImage function:

var displayImage = function() {
    if (index == pictures.length) { index = 0; }
    $("#" + pictures[index++]).fadeIn(1500).delay(3500).fadeOut(1500, displayImage);
};

TRY IT at jsfiddle

EDIT

On more careful reading of your question, I see that my original answer didn't do exactly what you needed. You have it set so that every five seconds, one will have faded out and the other one will have faded in. Currently, mine takes 6.5 seconds, since mine is all operating sequentially instead of concurrently. To make it come close to matching yours, just change the 1500s to 750s:

    $("#" + pictures[index++]).fadeIn(750).delay(3500).fadeOut(750, displayImage);

This will take the right amount of time. It's slightly different from yours, in that one fades out all the way before the other fades in. The alternative is to actually skip the fadeIn and keep the fadeout. This is a lot closer to the way yours looks.

    $("#" + pictures[index++]).show().delay(3500).fadeOut(1500, displayImage);

Or, make a very small fadein, to help reduce the flash of the new image:

    $("#" + pictures[index++]).fadeIn(100).delay(3500).fadeOut(1400, displayImage);

Final Edit (really!)

Ok, to get the fadeIn and fadeOut to work reliably at the same time, the solution was to use neither. I went back to using animate, instead. As a result, I had to completely rewrite the displayImage function, but this is exactly what you need:

var displayImage = function () {
    if (index == pictures.length) {
        index = 0;
    }

    $("#" + pictures[index]).show().delay(3500).animate({
        opacity: 0.2
    }, {
        step: function (now) {
            var idx = (index + 1) % pictures.length;
            var val = 1.2 - now;
            $("#" + pictures[idx]).show().css("opacity", val);
        },
        complete: function () {
            $("#" + pictures[index++]).hide();
            displayImage();
        }
    });
};

What this does is move the sequence to "show->fadeIn and Out" instead of "fade in -> show -> fade out". To make your transition smooth, I only fade it out to 0.2 instead of 0. The step function is what fades the other one in at the same time. Once the new pic is visible, I completely hide the old pic.

Here's the working fiddle for it.

Altri suggerimenti

$(document).ready(function() { 
   setInterval(example, 10000); // repeat every 10 seconds
});

function example() {
    $('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picFive').delay(20000).fadeIn(1500).delay(3500);
}

A better way would be to give each pic the same class such as 'fadeinout'. This will mean you don't have to re-write your code when you add/remove more pics.

eg

<img id="picFive" class="fadeinout" ....  
/* not sure if they are even <img>s but whatever they are*/

Then do

$(document).ready(function() { 
    beginFades();
});

function beginFades() {
    $('.fadeinout').each( function(i,el) {  // find all elements with fadeinout
        //for each one, trigger the start of the fading after i*5000 milliseconds
        //i is the index of the element as it was found by jQuery - this will be in
        //document order (which actually may not be what you have but I'm guessing        
        //it is)
        setTimeout(function(){
            makeImgFadeInOut($(el))
        }, i*5000);
    });
}


function makeImgFadeInOut(el) {
    //trigger a single fadeIn, fadeOut.
    //But add a callback function to the end of fadeOut which retriggers the whole        
    //thing
    el.fadeIn(1500).delay(3500).fadeOut(1500, function(){makeImgFadeInOut(el);});
}

WORKING DEMO (WITH DIVS)

You can use setInterval to loop it forever, or setTimeout to loop it for a specific duration.

<script type="text/javascript">

$(document).ready(function() { 
     setInterval(ImageSlider, 1000);
});

 function ImageSlider() {
    $('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
    $('#picFive').delay(20000).fadeIn(1500).delay(3500);
 }

</script>

If you want to have total control upon your elements you can use this:

 var elements = [{
   el: '#pic1',
   delay: 3500,
   fadeIn: 1500,
   fadeOut: 1500
},
{
  el: '#pic2',
  delay: 3500,
  fadeIn: 1500,
  fadeOut: 1500
 }
 //... other elements
]
var index = null;
(function loop(){
  index = index || 0;
  index = index % elements.length();
      $(elements[index].el).fadeIn(elements[index].fadeIn, function(){
      $(this).delay(elements[index].delay)
             .fadeOut(elements[index].fadeOut, function(){
                  index++;
                  window.setTimeout(loop, 5000);
              });
   })();

Edit : forgot to execute the first iteration of the loop function and removing the useless call for index inside the loop

The good thing about how this loop works is that it doesn't use the SetInterval function. and the code inside the loop need to finish what it does inside before iterating again. (you won't have this hideous bug if you click an other tab and go back to your carousel) @ElRoconno answer is pretty good too if you require less configuration

Use any of this-

setInterval() - executes a function, over and over again, at specified time intervals

setInterval(function(){alert("Hello")},3000);

setTimeout() - executes a function, once, after waiting a specified number of milliseconds.

setTimeout(function(){alert("Hello")},3000);

What is the difference between both setInterval and setTimeout

for you may be the setTimeout will not work as it will run only once after a delay and setInterval will go on to make continuous repetitive call until the window.clearInterval(intervalVariable) is been called

I have created an example on jsfiddler here. Basically you don't have to do this one at a time. Just get the whole collection of images as an array and loop over them. Hope this helps

$(document).ready(function () {
var arr = $('.pics')
arr.hide();

$(arr[0]).fadeIn(1500).delay(3500).fadeOut(1500);

var index = 1;
var maxIndex = arr.length - 1;

setInterval(function () {
    /*arr.hide();
     var pic = $(arr[index]);
     pic.show();
     */
    var pic = $(arr[index]);
    pic.fadeIn(1500).delay(3500).fadeOut(1500);


    index++;
    if (index >= maxIndex) {
        index = 0;
    }
}, 6500);

});

There's really no need for setInterval here since you can use the callback built-into .fadeOut(), nor having to enumerate an array of images. You can do something as simple as:

var idx = 0;
fade();
function fade() {
    if (idx >= $('img').length) idx = 0;
    $('img').eq(idx).fadeIn(1500).delay(3500).fadeOut(1500, fade);
    idx++;
}

jsFiddle example

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top