JS代码执行顺序背后的逻辑是什么? 单击按钮后,我希望背景变为红色,然后显示消息。但是,在我单击“确定”后,该消息首先出现并且颜色应用于背景 - > CodePen。 在点击“确定”之前,将背景设为红色的正确和正确方法是什么?
<html>
<head></head>
<body>
<button onclick="run()">Click me!</button>
</body>
</html>
&#13;
(.*)
&#13;
答案 0 :(得分:4)
代码按照您期望的顺序执行,但是,每个语句都不是同步的,因为它们调用了Webbrowser提供的功能。
浏览器执行在UI线程上不会发生Javascript。因此,当您更改DOM(允许Javascript与浏览器HTML交互的抽象)时,它会触发对UI(浏览器页面)的更新,该更新与javascript执行分开。底层DOM元素已更新,但实际UI会有非瞬时更新。
在代码中,更改DOM元素后,代码会立即触发浏览器显示警报。显示警报是特定于浏览器的行为,对于Chrome,它会暂停UI更新,并要求您在继续之前与警报进行交互。在Firefox中,在更新UI后会显示警报。
两个浏览器之间的行为只是浏览器呈现引擎和事件循环的实现方式的差异。
function run(){
document.body.style.backgroundColor = 'red';
setTimeout(function() {
alert('Contratulations!');
},0 );
}
&#13;
<html>
<head></head>
<body>
<button onclick="run()">Click me!</button>
</body>
</html>
&#13;
此答案提供了有关如何解决问题的更多信息,Why is setTimeout(fn, 0) sometimes useful?
通过调用setTimeout
,您将alert
显示添加到javascript事件循环的末尾,这为UI提供了足够的更新时间。
答案 1 :(得分:1)
这是因为alert()
来电是对模态对话框的调用。模式对话框是阻止UI执行任何其他操作的对话框,直到对话框关闭为止。这只是浏览器在JavaScript运行时移动到下一个语句之前不能足够快地呈现颜色的问题。重要的是要认识到alert()
实际上是window
对象的方法。你可以写window.alert()
。知道这一点后,您必须了解window
对象不是JavaScript语言的本机部分。 window
是一个浏览器对象,因此由浏览器管理,而不是JavaScript运行时。
我修改了您的代码以在控制台中显示消息,而不是警报。因为写入控制台是非UI阻止的,所以您会立即看到颜色变化。
function run(){
document.body.style.backgroundColor = 'red';
console.log('Contratulations!');
}
<html>
<head></head>
<body>
<button onclick="run()">Click me!</button>
</body>
</html>
答案 2 :(得分:0)
试试这个。
function run(){
document.body.style.backgroundColor = 'red';
setTimeout(function() {
alert('Contratulations!');
}, 0);
}
<html>
<head></head>
<body>
<button onclick="run()">Click me!</button>
</body>
</html>
setTimeout
在延迟后调用函数。在这种情况下,延迟为零,允许在创建警报之前更改背景,但不会产生任何明显的延迟。