6

我想在 jQuery 中动态设置超时。动态设置的超时函数需要使用 $("this"),但我似乎无法让它工作。

一个例子:

$("div").each(function(){
    var content = $(this).attr('data-content')
    setTimeout("$(this).html('"+content+"')",$(this).attr('data-delay'));
});​

http://jsfiddle.net/qmhmQ/

做这个的最好方式是什么?

4

6 回答 6

16
$("div").each(function(){
    var content = $(this).attr('data-content'),
        $this = $(this); // here $this keeps the reference of $(this)
    setTimeout(function() {

      // within this funciton you can't get the $(this) because
      // $(this) resides within in the scope of .each() function i.e $(this)
      // is an asset of .each() not setTimeout()
      // so to get $(this) here, we store it within a variable (here: $this) 
      // and then using it

        $this.html(content);
    }, $this.attr('data-delay'));
});​

演示

于 2012-05-09T08:30:52.623 回答
3

您的代码应如下所示:

  1. 传递一个函数而不是一个字符串。说明:将字符串传递给 setTimeout 时会出现问题,因为它在与原始范围不同的范围内运行,因此会出现错误。

  2. 使用 jQuerydata()方法

    $("div").each(function(){
         var content = $(this).attr('data-content'),
             $el = $(this),
             setContent = function(){
                $el.html(content);
             }
         setTimeout(setContent,$el.data('delay'));
    });​
    

您可以将函数分配给变量并将该变量作为参数传递给 setTimeout,这是最干净的方法。

于 2012-05-09T08:36:28.280 回答
3

使用闭包(一些 教程)。

使用字符串 withsetTimeout不是一个好主意。还要注意,因为如果在闭包内使用this它可以更改其上下文(即 call-site )。

如果使用数据属性,您可以使用 jQuery 数据函数。

$("div").each(function() {
  var instance = $(this);
  var content = instance.data('content');
  var method = function() {
    instance.html(content);
  };
  setTimeout(method, instance.data('delay'));
});
div {
  border: 1px solid black;
  margin: 5px;
  height: 1.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-content="fus" data-delay="1000"></div>
<div data-content="ro" data-delay="2000"></div>
<div data-content="dah" data-delay="5000"></div>

于 2012-05-09T08:36:45.420 回答
2

我只是在扩展上面的答案之一,

  1. 在 JavaScript 中使用 class 或 id 来引用 div。这将避免页面中进一步的标签名称冲突。

所以你更新的 HTML 是,

<div data-content="fus" data-delay="1000" class="dv"></div>
<div data-content="ro" data-delay="2000" class="dv"></div>
<div data-content="dah" data-delay="5000" class="dv"></div>​

现在你更新的 JavaScript 代码是,

$(".dv").each(function(){
    var content = $(this).attr('data-content'),
    $this = $(this);
    setTimeout(function() {
       $this.html(content);
    }, $this.attr('data-delay'));
});​

主线在哪里

$这个 = $(这个);

我们将当前元素分配给 setTimeout 函数中使用的变量。

请参考这个链接

于 2012-05-09T08:46:05.093 回答
1

以下似乎是空白、可读性和揭示意图的良好折衷。

$('div').each(function(){
    var element = $(this)
    var content = element.attr('data-content')
    var delayms = element.attr('data-delay')
    var action = function() { element.html(content) }

    setTimeout(action, delayms)
})

见:http: //jsfiddle.net/wilmoore/LSs6g/

于 2012-09-14T19:11:17.340 回答
1

从 settimeout 中取出 $(this) 并将其保存在$("div").each(function(){这一行之后的局部变量 say 'self' 中

var self=$(this);

并进一步使用那个自我

于 2012-05-09T08:35:49.520 回答