如果我在Javascript事件处理程序中对DOM进行更改,这些更改是增量呈现,还是只在最后呈现一次
If I make DOM changes in a Javascript event handler, are the changes rendered incrementally, or just once at the end?
假设我有以下javascript事件处理程序:
function handleEvent(e){
document.body.style.backgroundColor = 'green';
longRunningFunction();
document.body.style.backgroundColor = 'red';
}
浏览器会先显示绿色背景,然后切换为红色吗?还是直接显示红色背景?
根据我的测试,它直接在事件处理程序的末尾显示红色。但是,这是规范的一部分,还是只是浏览器实现方式的附带因素?
更新:
我应该澄清,我不是"瞄准"这种效果。更确切地说,我想保证它不会发生而不会发生。我的一些事件处理程序改变了很多东西,如果我可以假设没有任何中间状态被呈现,这将使我的工作更轻松。
下面是JavaScript执行环境中会发生的事情:
-
document.body.style.backgroundColor
将其值更改为'green'
- 一个长时间运行的进程将会运行。
-
document.body.style.backgroundColor
将其值变为'red'
。
如果JavaScript线程被阻塞,backgroundColor
属性的变化将如何影响页面的外观是未指定的。
这里有一个例子。如果你点击hello
,你会看到一个轻微的延迟,然后背景会变成红色:
function handleEvent(e){
document.body.style.backgroundColor = 'green';
longRunningFunction();
document.body.style.backgroundColor = 'red';
}
function longRunningFunction() {
for(var i=0; i<2000000000; ++i) { +i; }
}
document.body.addEventListener("click", handleEvent);
<div>hello</div>
这是因为浏览器的渲染引擎在响应CSS属性的改变时被长时间运行的阻塞JavaScript函数阻塞了。这不是指定的行为,而是所有浏览器的实现现实。请参阅如何在脚本执行一些繁重的处理时强制浏览器重新绘制?对于类似的问题。
我认为任何给定的浏览器都可以选择在JavaScript线程并发运行一个单独的重绘线程,但我不相信目前任何主流浏览器都这样做。在这种方法中可能存在固有的竞争条件复杂性;我从来没有写过浏览器,所以我不知道。
如果你想要显示中间状态,你可以在将backgroundColor
设置为绿色后使用一个非常快速的setTiemout
调用,以清除JavaScript函数堆栈并允许渲染器重新绘制页面:
function handleEvent(e){
document.body.style.backgroundColor = 'green';
setTimeout(function() {
longRunningFunction();
document.body.style.backgroundColor = 'red';
}, 4);
}
这将longRunningFunction
和第二次颜色更改排队,以便将来在4毫秒内运行。在这空闲的4毫秒内,渲染器有机会重新绘制页面。
这是否说明了您的目标?
function handleEvent(e){
document.body.style.backgroundColor = 'green';
alert();
document.body.style.backgroundColor = 'red';
}
- Javascript匹配以从URL中删除部分文件名-替换最后一次出现的内容
- 正在查找最后一次出现的文本
- JavaScript只有在最后一次被调用时才运行函数
- 字符串拆分并获取第一次和最后一次出现
- Regex-从第二次出现到最后一次出现
- 我如何可以忽略以前的选择,只写最后一次选择
- 异步mongodb更新循环中最后一次迭代后的重定向
- 链接超时会导致最后一次超时被拒绝
- 变量在循环的最后一次迭代中变为未定义
- 将匹配字符串中最后一次出现的点的正则表达式
- 删除/隐藏链接后最后一次出现的字符串
- 如何获取单击元素的类值,并使用此值在 jquery 中最后一次出现此类之后放置一段 html 代码
- 如何在最后一次出现某个字符后获取 url 中的参数
- 在使用 CasperJS 遍历参数化 URL 时,仅执行最后一次迭代
- 在javascript中获取除最后一次外的所有模式
- 使用lookahead获取javascript中模式的最后一次出现
- 删除javascript中最后一次出现的字符串
- Javascript Regex匹配字符串最后一次出现后的所有内容
- 使用RegEx获取最后一次出现
- 如何使用Javascript正则表达式从可能的单词列表中获取单词的最后一次出现