0

I am looking for a way to keep on looping a couple of values. I am using a simple ajax load script, which get the value(s)(files) from a dataset from the target element. The re-loading of a file happens every XXXX second, so it will load the file over and over, but if there are more files present it should loop them all, and re-loop it....infinite

The example below is a basic idea how, I split the string and start with the first one, but how can i loop this(the best way), and keep it looping.

HTML

<div id="target" data-load="file1.php | file2.php | file3.php"></div>

jQuery

var fileTo = $('#target').data('widget-load').split("|");

setInterval(function(){
   $('#target').load(fileTo[0])
},1000);
4

4 回答 4

0

@Diode:在无限循环的情况下, shift && push 是更好的选择。忘了他们。在这种情况下,我建议如下:

var intervalId = setInterval((function(theArray)
{
    var target = $('#target');
    var current;
    return function ()
    {
        current = theArray.shift();
        target.load(current);
        theArray.push(current);
    };
})($('#target').data('widget-load').split("|")),1000);

尝试这个:

var intervalId = setInterval((function(theArray)
{
    var target = $('#target');//only search for this once, not on every call
    //to make infinite loop, copy the array
    var resetArr = theArray.slice(0);//use slice, if not a reference is assigned and both arrays will be altered 
    //Name is not required, if you want to use a name, pick a better one, next might be reserved (not sure)
    //best go for nextInterval, chose this one for explanation
    return function next()
    {
        //get first element, theArray is now 1 shorter
        target.load(theArray.splice(0,1)[0]);
        if (theArray.length === 0)
        {//no more files left -> this stops the interval
            //clearInterval(intervalId);
            //intervalId = null;
            //restore the array, the loop starts from file1 again --> infinite loop
            theArray = resetArr.slice(0);//copy the original value
        }
    }
})($('#target').data('widget-load').split("|")),1000);

这可能有点密集,但我在 chrome 控制台中尝试了一个简单的单行版本:

foo = setInterval((function(arr){ return function(){alert(arr.splice(0,1)[0]); if (arr.length === 0){ clearInterval(foo);}};})([1,2,3]),1000);

它就像一个魅力。
这个怎么运作:

intervalId保存间隔的 erm id ......有点参考。只要设置好了,该函数就会被调用 every 1000ms。我没有传递一个简单的函数作为第一个参数,而是创建了一个函数,并立即调用它。我传递给无名函数 ( theArray) 的参数可以被调用的函数访问next,它是匿名函数的返回值。它是在函数内部创建的,因此它可以访问其母函数的所有变量,即使在函数返回之后也是如此。
这意味着theArray除了函数之外的其他任何地方的值都超出了范围next,这是我们间隔的实际回调。没有什么可以干扰的价值theArray,任何外部代码都不能覆盖任何内容,与使用全局变量相比,这是一种更安全的方法。
这同样适用于变量target:它是在匿名的母亲函数中声明和初始化的,该函数被调用一次,然后被 GC'ed。该变量仍然存在,并引用了一个 jQuery 对象。DOM 只被搜索过一次,用于该元素,但每次新调用该next函数都可以访问该对象。这样做一次,速度差异很小,一直这样做,你的脚本(很多)更有效率!

因此,间隔:每 1000 毫秒,next被调用一次。theArray它从作为其创建者(该匿名函数)的参数()的数组中转移第一个值。当该数组为空时,clearInterval调用该函数以停止该批次。所有文件都已加载,继续进行没有意义。
一旦发生这种情况,theArray, next-function 和所有其他变量 ( target) 就会超出范围,所以没有全局变量,只是一块漂亮、干净的内存,这总是一件好事。我假设此代码将作为事件处理程序的一部分触发,在这种情况下,您只需将其复制粘贴到处理程序中,同样不会创建全局变量。

如果此代码将成为全局范围的一部分,则只需将其全部包装在自调用函数中即可轻松避免全局变量:

(function()
{
    var intervalId = setInterval((function(theArray)
    {
        //...
    })($('#target').data('widget-load').split("|")),1000);
})();

你都准备好了。恕我直言,这是解决这个问题的最好、最安全和最有JS 意识的方法。JavaScript 是关于函数的,你越多地利用它们,语言就越喜欢它。事实上,它会通过揭示其隐藏的表现力来感谢你。

即使您决定不使用此答案,也请阅读诸如闭包之类的内容以及如何充分利用函数范围。你很快就会发现自己以一种全新的方式编写代码,保证 :)

于 2012-08-16T16:42:18.397 回答
0

您可以使用 setTimeout("function",delay) 在自身内部继续调用相同的函数,并延迟几毫秒。

于 2012-08-16T16:31:10.290 回答
0
var fileTo = $('#target').data('widget-load').split("|");

setInterval(function(){
   var file = fileTo.shift();   // `shift` gives the file at 0
   $('#target').load(file);     // load it
   fileTo.push(file);           // `push` adds it at the end of the array
},1000);
于 2012-08-16T17:12:15.577 回答
-1
var $target = $('#target'),
    fileTo = $target.data('widget-load').split("|"),
    i = 0;

setInterval(function(){
   $target.load(fileTo[i]);
   i++;
   if (i === fileTo.length)
      i = 0;
},1000);
于 2012-08-16T16:31:43.963 回答