Javascript DOM操作未按顺序执行
我正在寻找一个解决方案,甚至只是在下面的例子中寻找一些“幕后”理论 DOM的操作似乎是以非阻塞方式进行的。换句话说,没有流控件等待DOM语句的执行 在本例中: 在onclick事件之后执行两条语句Javascript DOM操作未按顺序执行,javascript,dom,race-condition,flow-control,Javascript,Dom,Race Condition,Flow Control,我正在寻找一个解决方案,甚至只是在下面的例子中寻找一些“幕后”理论 DOM的操作似乎是以非阻塞方式进行的。换句话说,没有流控件等待DOM语句的执行 在本例中: 在onclick事件之后执行两条语句 将文本从左向右移动 document.getElementById('text').className = 'tr'; document.getElementById('text').className = 'tr'; 循环一段时间以停止执行 for(var i = 0,temp=1000000
document.getElementById('text').className = 'tr';
document.getElementById('text').className = 'tr';
for(var i = 0,temp=1000000000; i<temp;i++){var dummy=0;}
for(var i = 0,temp=1000000000; i<temp;i++){var dummy=0;}
如果只是几毫秒的分辨率,setTimeout也是绝对正确的方法 您的循环正在阻止浏览器更新。
此外,循环处理所需的时间也不可预测。对于智能JavaScript编译器来说,如果循环没有任何好处,那么由于优化,可以省略循环。setTimeout是绝对正确的方法,如果它只是几毫秒的分辨率 您的循环正在阻止浏览器更新。
此外,循环处理所需的时间也不可预测。关于智能JavaScript编译器,如果循环没有任何好处,那么由于优化,循环可以省略。我意识到这是一个老问题,但我想解释一下为什么循环会阻止文本向右更改 浏览器以每秒60次的最大速率刷新窗口。这将通过事件循环完成,事件循环也会安排其他操作。首先,运行所有同步代码。然后,事件循环将经历延迟操作;包括影响窗口重绘的因素(例如,更改DOM元素中的类并应用样式) 这就是这里发生的事情。触发事件时,将首先执行同步代码。即: 1) 将
tr
作为类名分配给DOM元素数据(但不分配给显示的DOM本身。换句话说,如果在开发工具上检查元素,此时将看不到更改)
2) 运行循环
同步代码完成后,事件循环将查看还需要执行哪些操作。重新油漆将在这里进行。因此,此时您将看到dev工具上的元素获取tr
类,文本向右移动
此时安排要执行的操作的最佳方法是通过requestAnimationFrame
(不一定是setTimeout
)。因此:
document.getElementById('text').className='tr';
requestAnimationFrame(()=>{
// ...
} );
我已经更改了您的代码,以便更好地说明我所说的内容:
document.addEventListener('mousedown',shift\u text,false);
函数shift_text(){
requestAnimationFrame(()=>{
console.log('requestAnimationFrame 1')
} );
//先执行后停止
document.getElementById('text')。className='tr';
log('className now is',document.getElementById('text').className);
requestAnimationFrame(()=>{
console.log('requestAnimationFrame 2')
} );
//大圈停车
对于(var i=0,temp=3000000000;i我意识到这是一个老问题,但我想解释一下为什么循环会停止文本向右的更改
浏览器以每秒60次的最大速率刷新窗口。这将通过事件循环完成,该循环还计划其他操作。首先,运行所有同步代码。然后,事件循环将执行延迟操作;包括影响窗口重新绘制的操作(例如,更改DOM元素中的类并应用样式)
这就是此处发生的情况。触发事件时,将首先执行同步代码。即:
1) 将tr
作为类名分配给DOM元素数据(但不分配给显示的DOM本身。换句话说,如果在开发工具上检查元素,此时将看不到更改)
2) 运行循环
同步代码完成后,事件循环将看到还需要做什么。重新绘制将在此处进行。因此,此时您将看到开发工具上的元素获取tr
类,文本向右移动
安排此时要执行的操作的最佳方法是通过requestAnimationFrame
(不一定是setTimeout
)。因此:
document.getElementById('text').className='tr';
requestAnimationFrame(()=>{
// ...
} );
我已经更改了您的代码,以便更好地说明我所说的内容:
document.addEventLis
document.getElementById('text').className = 'tl';
class name now is tr // Despite the text still being on the left.
sync code is done // After a while due to the large loop.
requestAnimationFrame 1 // At this point, the text will be on the right.
requestAnimationFrame 2