在第一个函数完成将 CSS 样式应用于元素后运行 JavaScript 函数 - 回调不起作用



如片段所示,我有两个按钮。单击任一按钮时,应按此顺序发生以下情况:(1( 颜色变为红色,(2( 按钮隐藏 (3( 显示带有按钮 ID 的警告框。

我尝试将 function2 作为回调参数传递给 function1,但实际发生的是首先显示警报框,然后按钮消失而颜色没有变化。

我不明白为什么会这样。任何帮助/提示将不胜感激!

var items = document.getElementsByClassName("buttons");
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", function() { function1(this.id, function2); });
}
function function1 (uid, callback) {
document.getElementById(uid).style.backgroundColor = "red";
document.getElementById(uid).style.display = "none";
callback(uid);
}
function function2 (clicked_id) {
alert(clicked_id);
}
<p>Clicking on a button should change its color to red, hide it and then display an alert box with the button's ID:</p>
<div class="main">
<button id="btn1" class="buttons">Button 1</button>
<button id="btn2" class="buttons">Button 2</button>
</div>

你需要给浏览器的UI线程(这是运行JavaScript代码的线程(时间来重新绘制页面,然后再用alert停止世界。或者更好的是,根本不要使用alert

通常可以通过以下方法将其延迟一个事件循环周期

setTimeout(callback, 0, uid);

。但并非总是如此。到目前为止,我发现的最有效的方法(但我不必经常这样做,因为我不经常使用停止世界函数alertconfirmprompt(是在requestAnimationFrame调用中使用setTimeout

requestAnimationFrame(() => {
setTimeout(callback, 0, uid);
});

在应用更改后,在浏览器准备重新绘制之前调用外部回调,因此我们在此之后安排调用。

更新的代码段:

var items = document.getElementsByClassName("buttons");
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", function() { function1(this.id, function2); });
}
function function1 (uid, callback) {
document.getElementById(uid).style.backgroundColor = "red";
document.getElementById(uid).style.display = "none";
requestAnimationFrame(() => {
setTimeout(callback, 0, uid);
});
}
function function2 (clicked_id) {
alert(clicked_id);
}
<p>Clicking on a button should change its color to red, hide it and then display an alert box with the button's ID:</p>
<div class="main">
<button id="btn1" class="buttons">Button 1</button>
<button id="btn2" class="buttons">Button 2</button>
</div>