【问题标题】:setTimeout passing arguments issuesetTimeout 传递参数问题
【发布时间】:2013-06-20 23:30:29
【问题描述】:

我正在尝试传递元素索引并延迟滑动每个列表项内容

这是我的代码

    for(var i = 1; i <= $("#colContainer li").length ; i++) {
        var el = $("#colContainer li:nth-child(" + i + ") .colContent");

        var delay = function() {
            slide(el);
        };
        setTimeout(delay, 10);
        function slide(el){
            el.slideUp();
        };
    };

但每次只有最后一个向上滑动

我期望他们从索引 1 滑动到末尾延迟

我也试过了

    index = $(this).parent("li").index();
    for(var i = 1; i <= $("#colContainer li").length ; i++) {
        (function(i) {
            var el = $("#colContainer li:nth-child(" + i + ") .colContent");

            var delay = function() {
            slide(el);
            };
            setTimeout(delay, 10);
            function slide(el){
            el.slideUp();
            };
        })(i);
    };

但它们都同时滑动,我想要索引 1 幻灯片,然后是索引 2 和 ...

对于循环有什么办法吗??

【问题讨论】:

标签: javascript jquery settimeout


【解决方案1】:

这是因为var el 的作用域是功能块,而不是循环块。

试试这样的:

for( var i=1; ......) { (function(i) {
    var el = ...
    // rest of your code, unchanged
})(i); }

【讨论】:

  • @KamranAsgari 如果您更新的问题是您尝试过的,那么您在新的function 之前缺少(
  • 是的,他们都一次滑动,我想要第一张幻灯片,然后第二张幻灯片......
  • 那么你有一个不同的问题 - 你解决了“最后一个”问题,现在你唯一的问题是你应该为每个增加 setTimeout 延迟。也许使用10*i 而不是10
  • @Mamran,人眼无法检测到 10 毫秒。将它乘以 2 或 3 并没有太大变化……
  • @KamranAsgari 谢谢,但我得跑了,没时间好好写。来吧,把它给别人。
【解决方案2】:

您需要一个闭包来限定循环的每次迭代的 el 值。

for(var i = 1; i <= $("#colContainer li").length ; i++) {
  var el = $("#colContainer li:nth-child(" + i + ") .colContent");
  (function(el) {
    setTimeout(function(){
        el.slideUp();
    },10);
  })(el);
}

但是,这仍然会导致它们同时进行动画处理,如果这是所需的结果,您可以使用 jQuery 一步完成所有操作。 如果您希望他们一次制作一个动画,您可以这样做:

for(var i = 1; i <= $("#colContainer li").length ; i++) {
  (function(i) {
    var el = $("#colContainer li:nth-child(" + i + ") .colContent");
    setTimeout(function(){
        el.slideUp();
    }, i * 10);
  })(i);
}

【讨论】:

  • 他们都一起滑动,我更新了问题,我想要第一张幻灯片,然后是第二张,然后是第三张...
  • 在这种情况下,将 i 改为范围并使用 i*10 进行超时。我已经更新了我的答案,让它们单独滑动。
【解决方案3】:

您是想让它们排队还是延迟 10 毫秒,然后它们全部滑上去?

您需要for 循环吗?

下面的不是后者吗?

setTimeout(function() {
   $("#colContainer li .colContent").slideUp();
}, 10);

排队幻灯片示例:

(function slideContent(index) {
   $("#colContainer li:nth-child(" + index + ") .colContent").slideUp();
   if ($("#colContainer li:nth-child(" + (index + 1) + ") .colContent").length == 1) {
      setTimeout(function() { slideContent(index + 1); }, 250);
   }
})(1);

【讨论】:

  • @KamranAsgari,对,这就是我的想法,因此您应该考虑我在回答中所说的话,因为即使它被否决(不知道为什么)它也正确识别了问题.. . 您的幻灯片不会按顺序向上滑动,它们会同时向上滑动。 (虽然 10 毫秒基本上算不了什么,所以,你甚至无法区分!)将其更改为 250 毫秒,你就会明白我的意思了。
  • 所以没有办法使用 for 循环?你说?
  • 对于链接(一个接一个)我会推荐 Alex D 的第二个解决方案:stackoverflow.com/a/17225554/1441046
  • 不,您可以使用 for 循环并按照其他人所说的那样更改延迟。我用更多有用的信息编辑了我的问题。我不会使用 for 循环,但是,我会在它们执行时将它们链接起来依次调用,但这完全是个人喜好问题。
  • 更新了 Alex D 的链式解决方案的替代方案,执行排队的幻灯片动画。添加了更多延迟以帮助更好地说明这一点。
【解决方案4】:

除非您的意图是让它们同时具有动画效果,否则您不能以这种方式将它们设置为循环。如果这样做,它们会(几乎)同时执行,正如您所说,您实际上只会看到最后一个。

您需要从前一个完成后触发每个连续的。将它们与回调链接在一起。

delay 应该设置下一个 setTimeout。然后你就会得到你想要的结果。

编辑 鉴于此处的其他答案,我将补充一点,您可能希望将暂停时间从 10 毫秒增加到 100 毫秒,然后使用其他人建议的 *i 解决方案。将 10 毫秒乘以 i 不会以明显延迟的方式为您带来很多。我会从 100 毫秒开始,如果这太生涩,则以 10 毫秒的增量从那里向下移动,直到你有一个让你开心的动画。

【讨论】:

  • 我以前做过,例如 4 CONSECUTIVE setTimeout 但我想用 for 循环来做
  • 也许我不明白你的问题。在我看来,您正试图同时提示所有动画。
  • @DonRhummy,关闭将解决他的范围问题,但我不认为这将有助于防止他的所有动画一次触发......除非我忽略了一些东西。也许OP希望所有项目同时向上滑动,在这种情况下,Kolink的解决方案确实是正确的。
猜你喜欢
  • 1970-01-01
  • 2017-12-05
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多