DOM更改未立即执行

时间:2019-05-22 15:42:42

标签: javascript jquery html dom

所以我有一个隐藏的元素,我想显示它,然后立即触发警报。

我尝试使用jquery:

$('#myElement').show();
alert('test');

我也尝试仅使用常规javascript:

document.getElementById('myElement').setStyle('display: block');
alert('test');

但是,在两种情况下,我都看到运行该警报时,仍然看不到我的元素,然后关闭警报后,该元素开始显示。

为什么在更新DOM之前运行警报?显示元素后,我是否有任何方法可以强制DOM更新,或者是否需要添加手动超时?

我已经尝试过使用$ .then()和$ .done()了,但是似乎都不起作用。

3 个答案:

答案 0 :(得分:4)

由JS触发的浏览器重画在主JavaScript事件循环上运行。

DOM正在更新,但是直到JS不忙于其他操作时,DOM的渲染才完成。

alert()被阻止,因此主事件循环上的所有JS都将暂停,直到被关闭为止。

您可以等待动画帧后再运行警报。

document.getElementById('myElement').setStyle('display: block');
requestAnimationFrame(() => alert('test');)

答案 1 :(得分:2)

这是因为alert()是一种模式操作,它阻止浏览器的UI线程更新。在上面的代码中,当您调用alert()时,DOM仍在更新过程中,但尚未完成重绘,但是直到用户关闭alert()为止,该线程仍无法完成

您有三种解决方案。首先,您可以将alert()设置为超时来延迟它:

$('#myElement').show();
setTimeout(function(){
  alert('test');
}, 20); // 20ms should be a long enough delay even on the slowest machines

第二,您可以使用一个库来显示DOM本身内的非模式警报,即。 Notify

最后,假设您的目的只是为了测试/调试,您可以使用console.log(),因为它不是模态操作:

$('#myElement').show();
console.log('test');

要查看控制台,请在浏览器中按 F12 。请注意,此方法应与console.dir()一起始终用于调试,而不是alert()

答案 2 :(得分:-1)

如果您使用的是jQuery,则可以在执行show()之后添加回调。

文档链接:http://api.jquery.com/show/

$('#myElement').show(400, function() {
   alert('test')
})