简体   繁体   English

Run JavaScript function after the first function completes applying CSS styles to an element - callback not working

[英]Run JavaScript function after the first function completes applying CSS styles to an element - callback not working

As shown in the snippet, I have two buttons.如片段所示,我有两个按钮。 When either button is clicked, the following should happen in this order: (1) colour changes to red, (2) button is hidden (3) alert box with the button ID is displayed.单击任一按钮时,应按此顺序发生以下情况:(1) 颜色变为红色,(2) 按钮被隐藏 (3) 显示带有按钮 ID 的警报框。

I have tried passing function2 as a callback parameter to function1 but what actually happens is the alert box gets displayed first and then the button disappears without the colour change.我尝试将 function2 作为回调参数传递给 function1,但实际发生的是警报框首先显示,然后按钮消失而没有颜色变化。

I don't understand why this is happening.我不明白为什么会这样。 Any help/tips would be appreciated!任何帮助/提示将不胜感激!

 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>

You need to give the browser's UI thread (which is the thread your JavaScript code runs on) time to repaint the page before you stop the world with alert .在使用alert停止世界之前,您需要给浏览器的 UI 线程(这是您的 JavaScript 代码运行的线程)时间来重新绘制页面。 Or better yet, don't use alert at all.或者更好的是,根本不要使用alert

You can usually get away with delaying it by one event loop cycle via通常可以通过一个事件循环周期延迟它

setTimeout(callback, 0, uid);

...but not always. ...但不总是。 The most effective way I've found to date (but I don't have to do this often, because I don't use the stop-the-world functions alert , confirm , or prompt often) is to use the setTimeout inside a requestAnimationFrame call:迄今为止我发现的最有效的方法(但我不必经常这样做,因为我不经常使用 stop-the-world 函数alertconfirmprompt )是在 a 中使用setTimeout requestAnimationFrame调用:

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

The outer callback is called just before the browser is ready to repaint after your changes have been applied, so we schedule a call after that.在应用您的更改后,在浏览器准备好重新绘制之前调用外部回调,因此我们在此之后安排调用。

Updated Snippet:更新片段:

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM