如何在 jQuery .each() 的每次迭代之间添加暂停?

Posted

技术标签:

【中文标题】如何在 jQuery .each() 的每次迭代之间添加暂停?【英文标题】:How to add pause between each iteration of jQuery .each()? 【发布时间】:2011-07-09 07:31:03 【问题描述】:

我正在获取一个 jQuery 对象数组,然后通过 .each() 修改数组中的每个单独的 jquery。

在这种情况下,我更新了类名以触发 -webkit-transition-property 以利用 css 转换。

我希望在每个 css 转换开始之前有一个暂停。我正在使用以下内容,但每次更新之间没有延迟。相反,它们似乎都在同时更新。

function positionCards() 
  $cards = $('#gameboard .card');
  $cards.each(function() 
      setTimeout( function() addPositioningClass($(this)); , 500 )
  );


function addPositioningClasses($card)
  $card
    .addClass('position')

我希望 setTimeout 能解决这个问题,但它似乎不起作用。有没有办法在每个对象的每个 CLASS 名称更新之前完成暂停?

【问题讨论】:

尝试在 addPositioningClass 函数周围使用引号,如下所示: setTimeout( 'addPositioningClass($(this))', 500 ) 您能否增加每次迭代的超时时间,例如 500,1000,1500... 【参考方案1】:

很抱歉挖掘了一个旧线程,但这个提示可能对类似问题有用:

$cards.each(function(index) 
    $(this).delay(500*index).addClass('position');
);

【讨论】:

请注意,delay 仅适用于动画队列,不会用于例如css()(见here) 延迟.addClass()时必须使用.queue()(和.dequeue()):$(this).delay(500*index).queue(function() $(this).children('.flipcontainer').addClass('visible').dequeue(); ); @aksu 您应该复制那里的内容并将其作为答案,因为它在 cmets 中丢失了,而您的答案帮助我使其正常工作。【参考方案2】:

我将此作为评论添加,但现在我已正确阅读并回答了我自己的问题,这可能会起作用:

function positionCards() 
  var $cards = $('#gameboard .card');

  var time = 500;

  $cards.each(function() 
      setTimeout( function() addPositioningClass($(this)); , time)
      time += 500;
  );

【讨论】:

您的代码与 OP 有何不同?存在范围错误,因为 addPositioningClassessetTimeout 的上下文中不存在 @JohnP - @DA 声明代码有效,但所有元素都同时定位,我不知道函数的范围是问题的一部分...... 我只是在小提琴中试了一下,它不起作用。我可能弄错了,但我根本看不出该代码是如何工作的。 @JohnP - @DA 说 --> “我正在使用以下内容,但每次更新之间没有延迟。相反,它们似乎都在同时更新。” 解决方案:这也存在于这个 Git 中:gist.github.com/Zackio/7648481【参考方案3】:

此代码将添加将初始延迟设置为 50 毫秒。然后对于通过“.row”类的每个循环,它将增加额外的 200 毫秒延迟。这将为每一行创建一个很好的延迟显示效果。

$( document ).ready(function() 
    // set inital delay
    var dtotal = 50;
    $(".row").each(function() 
    //add delay to function
      $(this).delay(dtotal).show();
    //add 200ms to delay for each loop
      dtotal = dtotal + 200;
    );
);

【讨论】:

最好是添加一些注释而不是随便乱扔代码。【参考方案4】:

看看这个,对我来说效果很好! :)

jQuery('.optiresultsul li').each(function(index) 
    jQuery(this).delay(500*index).animate( opacity: 1 , 500,function()
        jQuery(this).addClass('bgchecked');
    );
);

【讨论】:

【参考方案5】:

试试这个:

function positionCards() 
  $('#gameboard .card').each(function() 
      $(this).delay(500).addClass('position');
  );

老实说……我过去曾在某些情况下遇到过 $(this).delay() 行为不端的情况,而在其他情况下却表现得完美无缺。然而,这通常与 jQuery 动画调用相结合,而不是 DOM 属性操作。

请注意 .delay() 的功能与 setTimeout 不同。如需更多信息,请参阅the jQuery .delay() documentation。

据我所知,$().each 确实按程序执行,因此调用的下一次迭代应该只在前面的迭代完成后开始。

【讨论】:

我可能是错的,但是在阅读 jquery 文档时,看起来延迟只是为了延迟 jQuery 动画。我认为您在最后一段中也是正确的。问题是我没有延迟设置类的函数调用,而是延迟了设置类的时间。因此,它同时将延迟应用于所有 30 个元素,然后它们都延迟了相同的时间。【参考方案6】:

如果您只针对 Safari/ios,根据控制动画序列的确切时间对您的重要性,您可能应该避免任何涉及 JS 超时的解决方案。无法保证动画会在超时延迟的同时完成,尤其是在慢速处理器或后台有很多东西的机器上。更高版本的 webkit(包括移动 safari)确实允许通过@-webkit-keyframes 进行定时动画序列。 Webkit.org 有一个nice intro to it。它实际上很容易实现。

【讨论】:

我确实只针对 iOS(它是一个应用程序)。我不是在计时动画序列,而是计时要等多久才能更新类名,然后又会触发 webkit 转换 css。【参考方案7】:

如果您创建了一个每 500 毫秒调用一次自己的方法,那么应该可以做到这一点。以下代码应该可以工作。

var __OBJECTS = [];

$('#gameboard .card').each(function() 
    __OBJECTS.push($(this));
);

addPositioningClasses();

function addPositioningClasses() 
    var $card = __OBJECTS.pop();
    $card.addClass('position');
    if (__OBJECTS.length) 
        setTimeout(addPositioningClasses, 500)
    

在小提琴上测试:http://jsfiddle.net/jomanlk/haGfU/

【讨论】:

我需要进一步调查 .push() 。我没有意识到这一点!【参考方案8】:

.delay() 怎么样?

function addPositioningClasses($card)
  setTimeout(function()  $card.addClass('position'), 1000);

【讨论】:

我也一直想知道,但是直到今天我还没有找到可以应用这种方法的上下文。 据我所知,delay() 仅适用于 jQuery 动画。

以上是关于如何在 jQuery .each() 的每次迭代之间添加暂停?的主要内容,如果未能解决你的问题,请参考以下文章

每次在jquery中获取最后一次迭代

每次 for-each 迭代获取 2 个结果值

JQuery源码分析

如何在 $.each 中的 jquery prependTo 之前和之后添加静态 HTML

Jquery .each 迭代访问此子内容

each()