为什么这个ID的返回未定义?
var time = 200;
$('.block').each(function () {
setTimeout(function () {
console.log($(this).attr('id'));
}, time);
time += 200;
});
但这会返回ID就好了吗?
var time = 200;
$('.block').each(function () {
console.log($(this).attr('id'));
setTimeout(function () {
}, time);
time += 200;
});
我正在尝试一次一个地创造一种冒泡效果,这让我发疯了
答案 0 :(得分:5)
回调内的this
(全局对象)的值与外部作用域(当前元素)的值不同。使用以下命令关闭对正确值的引用:
$('.block').each(function () {
var that = $(this);
setTimeout(function () {
console.log(that.attr('id'));
}, time);
time += 200;
});
这是有效的,因为传递给setTimeout
的函数是一个闭包,它保留对其词法范围(包括that
)中声明的变量的访问权。
这里的一般课程是函数内this
的值是动态确定的,完全取决于 函数的执行方式:
this
显式设置为当前元素(使用call
/ apply
)。 浏览器在全局上下文中执行内部函数,这就是this
的值为window
的原因。这个简单的测试证明了最后一点:
setTimeout(function() {
alert(this === window); // true
}, 1000)
在现代浏览器中,上述解决方案的替代方法是使用bind
:
$('.block').each(function () {
setTimeout(function () {
console.log($(this).attr('id'));
}.bind(this), time);
time += 200;
});
答案 1 :(得分:1)
当setTimeout
运行时,this
的值已更改。要解决此问题,您可以在this
循环中缓存.each()
值,以便setTimeout
中的匿名函数可以使用它:
var time = 200;
$('.block').each(function () {
var $this = $(this);
setTimeout(function () {
console.log($this.attr('id'));
}, time);
time += 200;
});
以下是演示:http://jsfiddle.net/FRzWc/
此外,如果您想要提高循环的性能,请使用$.each()
代替.each()
:
var time = 200;
$.each($('.block'), function () {
var $this = $(this);
setTimeout(function () {
$this.text($this.attr('id'));
console.log($this.attr('id'));
}, time);
time += 200;
});