首页 > 解决方案 > 在第一个函数完成将 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>

标签: javascripthtmlcss

解决方案


在使用alert. 或者更好的是,根本不要使用alert

通常可以通过一个事件循环周期延迟它

setTimeout(callback, 0, uid);

...但不总是。迄今为止我发现的最有效的方法(但我不必经常这样做,因为我不使用 stop-the-world 函数alertconfirmprompt经常)是使用setTimeout内部requestAnimationFrame调用:

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>


推荐阅读