【问题标题】:How to pass 'this' into a setTimeout callback如何将“this”传递给 setTimeout 回调
【发布时间】:2012-02-28 03:31:20
【问题描述】:

css

.item {
  display: none;
}

html

<div>
  <div class="item">machin</div>
  <div class="item">chose</div>
  <div class="item">chouette</div>
  <div class="item">prout</div>
</div>

我正在使用 jQuery,我想让每个 .item 出现在一个随机的小计时器之后,例如:

javascript

$('.item').each(function () {
  itm = $(this);
  setTimeout(function () {
    itm.fadeIn(1000);
  }, Math.floor(Math.random() * 1000));
})

这里itm 将始终包含最后一项,因为函数是在所有分配之后进行评估的。
我不能使用setTimeout() 的第三个参数,因为它不适用于 IE。
出于安全原因,不建议将setTimeout()eval 方法一起使用。

那么我怎样才能通过setTimeout() 访问我的对象呢?


编辑

我知道这个问题已经发布了。
但我认为它在 each() 上下文中有点具体。
现在有人完全改变了我的问题的标题,原来是 'setTimeout() - jQuery.each() this object parameter'

【问题讨论】:

  • setTimeout() 内部的 this 指的是全局对象。您上面的代码甚至不应该适用于最后一项。
  • 对不起,我实际上是在我的代码中使用 itm = $(this) 而不是 var itm = $(this),我更新了我的问题。那么现在我不知道该接受哪个答案:)
  • @PierredeLESPINAY 啊哈。 var itmitm 之间的区别在于,没有var 它是一个全局变量,而不是每次调用封闭函数的局部变量。这就是为什么 setTimeout 只看到列表中的最后一个元素。
  • 这实际上是问题

标签: javascript jquery scope settimeout


【解决方案1】:

您需要将this 存储在单独的变量中:

$('.item').each(function () {
  var me = $(this);
  setTimeout(function () {
    me.fadeIn(1000);
  }, Math.floor(Math.random() * 1000));
})

【讨论】:

    【解决方案2】:

    创建/使用closure

    $('.item').each(function () {
      var that = this;
    
      setTimeout(function () {
        $(that).fadeIn(1000);
      }, Math.floor(Math.random() * 1000));
    })
    

    http://jibbering.com/faq/notes/closures/

    https://developer.mozilla.org/en/JavaScript/Guide/Closures

    【讨论】:

    • 由于OP无法让JQuery的内置工具工作,这是迄今为止最简单最直接的方法
    【解决方案3】:

    这里的技巧是将this 保存到可以在setTimeout 回调中安全评估的本地

    $('.item').each(function () {
      var self = this;
      setTimeout(function () {
        $(self).fadeIn(1000);
      }, Math.floor(Math.random() * 1000));
    });
    

    【讨论】:

      【解决方案4】:

      试试这个:

      $('.item').each(function () {
       var myVar = $(this);
      setTimeout(function () {
      myVar.fadeIn(1000);
      }, Math.floor(Math.random() * 1000));
      })
      

      【讨论】:

        【解决方案5】:

        试试这个:

            $('.item').each(function () {
                var elm = this;
              setTimeout(function () {
                $(elm).fadeIn(1000);
              }, Math.floor(Math.random() * 1000));
            })
        

        我无法解释它为什么起作用,但我认为这是对 setTimeout 中另一个“this”的引用。

        http://jsfiddle.net/Pdrfz/

        【讨论】:

          【解决方案6】:

          试试这个:

           $('.item').each(function () {
              var item =$(this);
              setTimeout(function () {
                      item.fadeIn(1000);
                  },
                  Math.floor(Math.random() * 1000));
             });
          

          【讨论】:

            【解决方案7】:

            setTimeout 执行之前each 循环将完成执行,它不会等待。同样在setTimeout 函数内部this 不会引用DOM 元素。

            试试这样的。

            function fadeItem(item){
               item.fadeIn(1000);
            }
            
            $('.item').each(function () {
              var $item = $(this);
              setTimeout(function () {
                fadeItem($item);
              }, Math.floor(Math.random() * 1000));
            });
            

            你也可以试试这样的。

            var $items = $('.item'), count = 0;
            
            function fadeItem(item){
               item.fadeIn(1000);
                if(count < $items.length){
                   setTimeout(function(){
                        fadeItem($items.eq(count++));
                   }, Math.floor(Math.random() * 1000));
                }
            }
            setTimeout(function(){
                fadeItem($items.eq(count++));
            }, Math.floor(Math.random() * 1000));
            

            【讨论】:

              【解决方案8】:

              不要使用setTimeout,使用jQuery自带的工具。

              $('.item').each(function () {
                 $(this).delay(Math.random() * 1000).fadeIn();
              })
              

              http://api.jquery.com/delay/

              工作示例:http://jsfiddle.net/qENhd/

              【讨论】:

              • @ShankarSangoli:确实如此。
              • 如果您注意到div's,请不要按应有的顺序排列fadeIn
              • @ShankarSangoli 我看不出有什么理由让它不起作用。请记住,这不是一个 for 循环,因此它没有相同的问题。
              • @ShankarSangoli:这不是要求,至少原始代码没有这样做。
              • 似乎无法使用 Bootstrap 3 工具提示? $('#elem').tooltip('show').delay(5000).tooltip('hide'); 隐藏似乎立即开火。
              猜你喜欢
              • 2011-01-08
              • 2010-11-14
              相关资源
              最近更新 更多