在.each枚举中插入“暂停”的最佳方法

时间:2011-07-18 21:17:20

标签: javascript jquery

使用jQuery'.each()'在一组元素上插入每个枚举的'pause'的最佳/推荐方式是什么?

$( '.someClass' ).each( function() {
    $( this ).trigger( 'click' ); //fire some request that appends a new div on the body 
    //wait for div to be appended to the DOM.  perhaps use the pause here
    //execute code once the div has been appended 
});

6 个答案:

答案 0 :(得分:3)

从技术上讲,你不能像在代码中建模那样做,因为JavaScript是单线程的,并且通常在浏览器(或标签)UI线程上运行 - 任何睡眠/延迟都会阻止浏览器重绘该页面也会阻止用户与该页面进行交互。

您需要安排浏览器定期调用您的代码。这样的事情可以解决问题:

var objects = $.makeArray($( '.someClass' ));

var callback;

callback = function() {
    var item = objects.shift();

    // Do something with item.

    if (objects.length != 0) {
        setTimeout(callback, 5000);
    }
}

setTimeout(callback, 5000);

请参阅an example

此解决方案假定您希望每个项目在最后一个项目完成处理后5秒内处理。这意味着:

  1. 如果您在处理每个项目时执行confirm()或其他操作,则下一个项目将在用户关闭对话框5秒后处理。
  2. 总执行时间为(5000N + T),其中N是初始列表中的项目数,T是处理每个项目所需的总时间。

  3. 这是一个可以使用的功能,它封装了这个功能:

    jQuery.eachWithDelay = function(sequence, delay, callback) {
        var objects = jQuery.makeArray(sequence);
    
        if (objects.length == 0) {
            return;
        }
    
        var f;
    
        f = function() {
            var item = objects.shift();
    
            if (callback(item) && objects.length != 0) {
                setTimeout(f, delay);
            }
        };
    
        setTimeout(f, delay);
    };
    

    叫做:

    $.eachWithDelay($('.someClass'), 5000, function(item) {
        // Do something with item
    
        return true; // Return true to continue iterating, or false to stop.
    });
    

    请参阅updated fiddle

答案 1 :(得分:0)

没有好办法在javascript函数中放置这样的延迟。

要在下一次增加工作之前合法延迟5秒,您需要获取作业所需的数据,将工作分成小块,设置5秒计时器并在每个计时器上完成一部分工作剔

以下是一种方法的实例:http://jsfiddle.net/jfriend00/tgBYk/

var objList = $('.someClass');
var cntr = 0;
var timeDelay = 5000;

function doNextIteration() {
    $(objList[cntr++]).html(cntr);   // your code here: This is the progress I'm showing in my demo
    if (cntr < objList.length) {
        setTimeout(doNextIteration, timeDelay);
    }
}

if (objList.length > 0) {
    doNextIteration();
}

答案 2 :(得分:0)

如果你有html喜欢

<div class="someClass">google</div>
<div class="someClass">facebook</div>
<div class="someClass">ARPANET</div>

将其包裹在$(document).ready() jsfiddle自动执行

$(".someClass").each(function(i){

       $(this).delay(i+"1000").fadeOut("slow");

    });

这里是小提琴http://jsfiddle.net/J6Mw6/1/

您可以设置您选择的时间

或者根据您编辑过的问题,这可能会有所帮助

http://jsfiddle.net/J6Mw6/2/

答案 3 :(得分:0)

如果由于某种原因必须使用.each,那么只要你在每次迭代中没有做大量的工作,这将使你非常接近:

var i = 0;
$( '.someClass' ).each( function() {
    setTimeout((function (el) {
        // do something with 'el'
    })(this), i * 5000);
    i += 1;
});

但是这样做会更正确(考虑到你的问题的措辞):

(function() {
    var arr = $('.someclass'),
        i = 0,
        fn = function() {
            var el = arr[i];

            // do something with 'el'

            i += 1;
            if (i < arr.length) {
                setTimeout(fn, 5000);
            }
        };
    fn();
})();

答案 4 :(得分:0)

因为我们只是在它周围抛出答案;继承人我的。不是每个人?

  

功能doTheDo(els){

 if(els.length == 0) return;

 $(els.shift()).click();
 setTimeout(doTheDo, 5000, els);
     

}

     

doTheDo($('#errors li')。toArray());

答案 5 :(得分:-4)

setTimeout(yourFunction(),5000);可能就是你想要的东西。但请记住,此函数将在5秒后执行yourFunction()。如果你的setTimeout后面有代码,那么它仍会立即执行,所以这取决于你想做什么。如果你真的想要暂停所有代码的执行,那么解决这个问题就更难了。您可以查看this文档,了解一些建议的解决方案/功能。但是使用JavaScript,如果不完全锁定CPU,很难完全停止执行。