如何在jQuery的.each()方法中增加迭代之间的暂停时间?

91

我正在获取一个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) - amosrivera
1
你能为每次迭代增加超时时间吗,比如500、1000、1500...? - Rob
8个回答

109
我把这个作为评论添加了进去,但是现在我已经正确阅读并回答了自己的问题,这个可能会起作用。
function positionCards() {
  var $cards = $('#gameboard .card');

  var time = 500;

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

1
你的代码与原始帖子(OP)有何不同?由于addPositioningClassessetTimeout的上下文中不存在,因此存在范围错误。 - JohnP
1
我刚在fiddle中尝试了一下,但它不起作用。我可能错了,但我看不出那段代码如何能工作。 - JohnP
3
@JohnP - @DA说--> "我正在使用以下方法,但每次更新之间没有延迟。相反,它们似乎都在同时更新。" - Rob
2
解决方案:也可以在此Git中找到:https://gist.github.com/Zackio/7648481 - Pranesh Janarthanan
1
当我尝试时,$(this) 是窗口。在我的each()函数中,它是元素,但在setTimeout内部,它是窗口。我似乎无法将元素传递给setTimeout的函数! - twistedpixel
显示剩余4条评论

54

抱歉挖起了一个老帖子,但这个技巧可能对类似的问题有用:

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

6
请注意,delay 仅适用于动画队列,在 css() 等函数中无效(请参见此处)。 - Yan Foto
23
当延迟执行.addClass()时,您需要使用.queue()(以及.dequeue()):$(this).delay(500*index).queue(function() { $(this).children('.flipcontainer').addClass('visible').dequeue(); }); - aksu
2
@aksu 你应该将你在那里的内容复制并制作成一个答案,因为它被淹没在评论中,而你的答案帮助我使其正常工作。 - adamj

11
如果你编写一个每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)
    }
}

在JSFiddle上测试过:http://jsfiddle.net/jomanlk/haGfU/


我需要进一步研究.push()。我之前不知道这个! - DA.

3

那么 .delay() 呢?

或者

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

我也一直在想这个问题,但到今天为止,我还没有找到可以应用这种方法的情境。 - Sandwich
3
据我所知,delay() 只适用于 jQuery 动画。 - DA.

1

试一下这个:

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

说实话...在某些情况下,$(this).delay()曾经表现不佳,但在其他情况下却完美无缺。然而,这通常是与jQuery动画调用一起使用的,而不是DOM属性操作。

请注意,.delay()的功能与setTimeout不同。有关更多信息,请参见jQuery .delay()文档

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


我可能错了,但在阅读jQuery文档时,它似乎只是用于延迟jQuery动画。我认为你在最后一段中也是正确的。问题在于我没有延迟设置类的函数调用,而是延迟了类的设置时间。因此,它将延迟应用于所有30个元素,并且它们都会延迟相同的时间。 - DA.

1

如果你只针对Safari/iOS,那么取决于你控制动画序列的确切时间有多重要,你可能应该避免任何涉及JS超时的解决方案。不能保证动画将在超时延迟的同时完成,特别是在处理器较慢或后台有很多东西正在运行的机器上。Webkit的后续版本(包括移动Safari)通过@-webkit-keyframes允许定时动画序列。Webkit.org有一个不错的介绍。实际上很容易实现。


我确实只针对iOS(它是一个应用)进行开发。我不是计时动画序列,而是计算等待多长时间才更新类名,然后触发WebKit转换CSS。 - DA.

0

看看这个,对我很有用!:)

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

-2
这段代码将把初始延迟设置为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;
    });
});

7
最好您加上一些评论,而不仅仅是把代码扔出来。 - woot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接