[英]setTimeout and anonymous function problem
这是我的代码,SetOpacity 被错误的值调用,为什么?
function SetOpacity(eID, opacity){
eID.style.opacity = opacity / 100;
eID.style.filter = 'alpha(opacity=' + opacity + ')';
}
function fade(eID, startOpacity, endOpacity){
var timer = 0;
if (startOpacity < endOpacity) {
for (var i = startOpacity; i <= endOpacity; i++) {
setTimeout(function() {SetOpacity(eID, i);}, timer * 30);
timer++;
}
}
}
这应该有效:
for (var i = startOpacity; i <= endOpacity; i++) {
(function(opacity) {
setTimeout(function() {SetOpacity(eID, opacity);}, timer * 30);
})(i);
timer++;
}
其工作原理如下:
function(...){...}
)并立即使用参数调用它(这就是function(){}
周围有括号的原因,因此您可以通过添加()
来调用它最后并传递参数)i
,它是函数内部的opacity
)是这个匿名函数的本地参数,所以它们在循环的下一次迭代中不会改变,你可以安全地将它们传递给另一个匿名函数( setTimeout
的第一个参数)您的原始版本不起作用,因为:
setTimeout
的函数包含对变量i
的引用(不是它的值),并且仅在调用此函数时才解析其值,而不是在将其添加到setTimeout
setTimeout
执行之前, i
就已经达到了endOpacity
( for
循环的最后一个值) 不幸的是 JavaScript 只有函数作用域,所以如果你在循环内创建变量并分配一个新的实际值,它就不会工作,因为只要函数中有一些var
,这些变量就会在函数执行时创建(和默认情况下undefined
)。 创建新作用域的唯一(简单)方法是创建一个函数(可能是匿名的)并在其中创建新变量(参数也是变量)。
这是一个关闭问题。 当您运行该函数时, i
已经处于endOpacity
。 通过创建另一个闭包,这将起作用:
function SetOpacityTimeout(eID, opacity, timer){
setTimeout(function() {SetOpacity(eID, opacity);}, timer * 30);
}
function fade(eID, startOpacity, endOpacity){
var timer = 0;
if (startOpacity < endOpacity) {
for (var i = startOpacity; i <= endOpacity; i++) {
SetOpacityTimeout(eID,i,timer);
timer++;
}
}
}
Kobi 在这个问题上有正确的想法。 不过,我建议您改用间隔。
这是一个示例:(您的 SetOpacity 函数保持不变,我在这里省略了它。)
function fade(eID, startOpacity, endOpacity){
var opacity = startOpacity;
SetOpacity(eID, opacity);
var interval = window.setInterval(function(){
opacity++;
SetOpacity(eID, opacity);
// Stop the interval when done
if (opacity === endOpacity)
window.clearInterval(interval);
}, 30);
}
这是我与 jquery 一起使用的示例。 "menuitem" 是 itemclass,jquery 检查 "recentlyOut" 类,看它是否需要向上滑动。
代码不言自明。
$(".menuitem").mouseenter(
function(){
$(this).addClass("over").removeClass("out").removeClass("recentlyOut");
$(this).children(".sub").slideDown();
});
$(".menuitem").mouseleave(
function(){
$(this).addClass("out").addClass("recentlyOut").removeClass("over");
setTimeout(function()
{
var bool = $(".recentlyOut").hasClass("over");
if (!bool)
{
$(".recentlyOut").removeClass("recentlyOut").children(".sub").slideUp();
}
}
, 400);
}
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.