setTimeout 忽略超时?(立即开火)

IT技术 javascript settimeout
2021-02-08 00:10:33

这是我第一次真正深入 JavaScript。当然我以前用过它,但我从来没有真正从头开始写过任何东西。

无论如何,我遇到了一个非常奇怪的问题,希望有人能帮我解决。

我正在尝试使 div 中的文本从黑色淡化为白色。很简单吧?

以下代码有效它会将颜色更改为白色,但是会忽略 500 毫秒的 setTimeout 时间。

如果您使用 Chrome 并查看 JS 控制台,您会很容易看到 doFade() 方法几乎是即时调用的,而不是每 500 毫秒调用一次。

谁能解释一下?

var started = false;
var newColor;
var div;
var hex = 0;

function fadestart(){
    if (typeof fadestart.storedColor == 'undefined') {
        div = document.getElementById('test');
        fadestart.storedColor = div.style.color;
    }
    if(!started){
        console.log('fadestart');
        newColor = fadestart.storedColor;
        started = true;
        setTimeout(doFade(), 500);
    }
}

function fadestop(){
    console.log('fadestop');
    div.style.color = fadestart.storedColor;
    started = false;
    hex = 0;
}

function doFade(){
    if(hex<=238){
        console.log(hex);
        hex+=17;
        div.style.color="rgb("+hex+","+hex+","+hex+")";
        setTimeout(doFade(), 500);
    }
}
3个回答

您需要去掉 上的括号doFade()

括号立即调用该函数。

只需使用它: doFade

@Surreal 实际上,您想传递不带括号的函数。引用它会在全局上下文中执行传递的代码片段,这可能会产生截然不同的结果。
2021-03-13 00:10:33
为什么他们让它立即与parens一起执行?是否可以让另一个函数返回动态用作超时的函数?
2021-03-13 00:10:33
很确定你不需要引号。您应该能够放置 doFade 或“doFade”。我认为不将字符串“doFade”转换为函数句柄可能会带来轻微的性能优势。
2021-03-17 00:10:33
@Surreal Dreams setTimeout 接受要评估的函数字符串作为回调。Javascript 中的函数是第一类对象,可以(通常)自由地传递。由于 Javascript 非常动态,因此几乎可以(并且应该)避免使用 eval。
2021-03-17 00:10:33
@akellehe、@deceze 和 @Angio:感谢您纠正我。对我的答案相当自信,但我知道如果我错了,你们会全神贯注,我会正确地学习。:) 那谢谢啦。
2021-03-24 00:10:33
setTimeout(doFade(), 500);

这一行表示“执行doFade(),然后传递它返回的任何值setTimeout,这将在 500 毫秒后执行此返回值。” 也就是说,你就doFade()在现场打电话

跳过括号将函数传递setTimeout

setTimeout(doFade, 500);

我认为你应该使用setTimeout(doFade, 500);setTimeout("doFade()", 500);

当然是。我的习惯是传递一个函数甚至一个内联函数。但是引用它总是另一种选择(当然在大多数情况下不是更好的选择)。
2021-03-13 00:10:33
刚刚注意到这个有一个更好的答案:stackoverflow.com/questions/3800512/...
2021-03-16 00:10:33
引用的调用也有效,但很糟糕。有关详细信息,请参阅 akellehe 的回答。
2021-03-31 00:10:33
不错,如果传递参数,引用的函数似乎是唯一的选择。
2021-04-05 00:10:33