sterix24
sterix24

Reputation: 2400

How do I handle this jquery loop?

I have an array of images that I want to loop through infinitely ie. 1, 2, 3, 1, 2, 3...

At first, I tried to do this using the following code:

var images = [
  "/images/image1.jpg",
  "/images/image2.jpg",
  "/images/image3.jpg"
];

var obj = { currentValue: 0 };
var maxValue = 2;            

//loop through the items
var infiniteLoop = setInterval(function() {
  if(obj.currentValue == maxValue) { 
    obj.currentValue = 0;                                           
  }

  // ... Code to fade in currentItem ...

  obj.currentValue++;
}, 5000);

I'd read that this is correct method of passing in a variable by reference but for some reason, I'm never able to set the obj.currentValue back to 0 when all the images have been looped through.

I figured an alternative way would be to set the value of an html field:

var images = [
  "/images/image1.jpg",
  "/images/image2.jpg",
  "/images/image3.jpg"
];

var maxValue = 2;            

//loop through the items
var infiniteLoop = setInterval(function() {
  if(parseInt($('#currentItem').val()) == maxValue) { 
    $('#currentItem]').val('0');                                           
  }

  //... code to fade in currentItem ...

  var tmp = parseInt($('#currentItem').val());
  tmp++;                                  
  $('#currentItem').val(tmp);
}, 5000);

<input type="hidden" id="currentItem" name="currentItem" value="0" />

However I'm still having the same problem. For some reason, whenever I hit the end of the image list, I'm unable to set the value of the hidden field and my infinite loop never gets to restart.

Am I missing something obvious here? I can't seem to figure out how to get this working.

If anyone has a more efficient method of achieving this I'd also be very grateful if you could share it :-)

Thanks

Upvotes: 0

Views: 196

Answers (5)

sg3s
sg3s

Reputation: 9567

So I rewrote your js a bit, with comments on how/why to do things

// Give your code a unique namespace using an immediately/self invoked annonymous function
(function (window) {

    // For better management we could use some more variables
    // slider.images.length replaces maxvalue
    var slider = { 
        images: [
          "/images/image1.jpg",
          "/images/image2.jpg",
          "/images/image3.jpg"
        ], 
        current: 0, // name your variables semantically, we know this is going to have a value so don't 'append' things to the name that are obvious
        time: 5000
    };

    // separated the function so we DRY
    function rotate() {
        // Remember that the images array is 0 indexed and length gives the total amount of 
        // items in the array which will be one more, if they're the same then we reset 
        // current to 0
        if(slider.current == slider.images.length)
            slider.current = 0;

        // Code to do w/e
        console.log(slider.images[slider.current], slider.current);

        slider.current++;
        window.loop = setTimeout(rotate, slider.time);
    }

    // only thing about intervals really, they never stop, and can never be stopped
    // so better thing to do is use a recursive timeout, and ideally it should be available 
    // somehow so you can stop it outside of the script itself, in this case we put the 
    // reference on window. (which is not ideal, anywhere else it makes sense is better)
    window.loop = setTimeout(rotate, slider.time);

}( window ));
​

And here in jsFiddle:

http://jsfiddle.net/sg3s/RGQxY/5/

You're using jquery to do things, that is fine, but you'll have to pass jQuery to be able to use it inside that immediately invoked function that wrapper could look something like this: (function ($, window) { /* code goes here */ }( jQuery, window ));.

Upvotes: 2

JMC
JMC

Reputation: 930

In your first example, change:

if(obj.currentValue == maxValue) { 

to

if(obj.currentValue > maxValue) { 

As it was, it couldn't process index 2, because it was being reset back to 0.

Upvotes: 1

Chris Disley
Chris Disley

Reputation: 1355

Could just use two loops.

while (1==1) 
{ // infinite loop
    for (int i = 0; i < images.length; i++) 
    { // loop images array
        console.log(images[i]);
    }
}

Prints the three image paths indefinitely.

Upvotes: 1

Selvakumar Arumugam
Selvakumar Arumugam

Reputation: 79850

If I understood correctly you want to loop thru when the counter reaches maxValue.. Try like below,

var images = [
  "/images/image1.jpg",
  "/images/image2.jpg",
  "/images/image3.jpg"
];

var maxValue = 2,
    counter = 0;

var infiniteLoop = setInterval(function() {
    var curIndex = (counter++ % (maxValue + 1));
}, 5000);

DEMO

Upvotes: 1

user1422442
user1422442

Reputation: 66

setInterval does not work properly at times. Have you tried setTimeout instead ? You can do the following and see if it works :

var images = [
  "/images/image1.jpg",
  "/images/image2.jpg",
  "/images/image3.jpg"
];

var obj = { currentValue: 0 };
var maxValue = 2;            

function fn() {
  if(obj.currentValue == maxValue) { 
    obj.currentValue = 0;                                           
  }

  // ... Code to fade in currentItem ...

  obj.currentValue++;
  setTimeout(fn,5000);

}

//loop through the items
var infiniteLoop = setTimeout(fn,5000);

Upvotes: 1

Related Questions