好的,我正在尝试做的是当点击一个按钮时会产生以下超时功能触发器:
setTimeout("if (document.getElementById(lightnum).style.backgroundColor=='green'){document.getElementById(lightnum).dataset.dead=1;document.getElementById(lightnum).style.backgroundColor='red';}", 3000);
我遇到的问题是因为变量lightnum会立即重复使用,所以当这个超时触发时,它会在创建settimeout时引用lightnum的当前值而不是lightnum的值。我在这里寻找的功能是当setTimeout在3秒后触发时它引用了最初创建时的lightnum值。
答案 0 :(得分:4)
首先,该代码应该是一个正确的函数而不是字符串。
关于你的问题,它修复如下:
var callback = (function(target) {
return function() {
if (target.style.backgroundColor == 'green') {
target.dataset.dead = 1;
target.style.backgroundColor = 'red';
}
};
})(document.getElementById(lightnum));
setTimeout(callback, 3000);
原始代码的问题在于,原始回调中的lightnum
将评估调用回调时的值,正如您已经看到的那样。你想要的是以某种方式将其“冻结”到它的初始值。
尝试这样做的一种方法是在设置超时(var copy = lightnum;
等)的函数内部创建一个本地副本。但是,这仍然不起作用,因为这次调用回调时它将对最后一次调用此函数时copy
的最后一个值进行操作(可能但不一定与原始代码的行为相同) )。
您真正想要做的是将lightnum
的当前值放在回调代码可以访问的 的某个位置;在JS中,唯一的方法是将它作为参数传递给函数。这需要上面那个时髦的“函数返回函数”语法:内部函数是实际需要的回调函数,外部函数是一个“防火墙”,它可以阻止任何外部干涉有问题的变量。
答案 1 :(得分:1)
使用闭包而不是字符串:
setTimeout(
(function(ln) {
return function() {
if (document.getElementById(ln).style.backgroundColor=='green') {
document.getElementById(ln).dataset.dead=1;
document.getElementById(ln).style.backgroundColor='red';
}
};
}(lightnum)),
3000
);
答案 2 :(得分:1)
“Jon”和“Ted Hopp”有正确的答案,但我可能只是在这里添加为什么功能更好: