原谅我糟糕的头衔,但是现在,我甚至不知道我不知道的事情。
如果我的HTML页面看起来像这样:
<html>
<head>
<script>
jQuery(document).ready(function(){
jQuery("#modalDiv").show();
//This part takes up to a few seconds to execute and blocks the browser
for(var i = 0; i < 10000; i++){
console.log("doing something");
}
jQuery("#modalDiv").hide();
});
</script>
<style>
#modalDiv{
background-color:red;
height:100px;
width:100px;
}
</style>
</head>
<body>
<div id="modalDiv"></div>
</body>
</html>
ID为“modalDiv”的元素永远不会显示在页面上。我不是要解决这个“问题”,我只是想了解幕后发生的事情,导致我的脚本表现得像它一样。
答案 0 :(得分:5)
在所有同步操作完成之前,浏览器不会对DOM进行更改,并且您的代码会将控制权返回给主事件循环。这允许您对页面进行大量更改,而无需用户查看所有中间表单 - 它会等到您完成后才会显示最终结果。
强制立即更新的一种方法是使用动画。
$(function () {
jQuery("#modalDiv").show(5000);
//This part takes up to a few seconds to execute and blocks the browser
for (var i = 0; i < 10000; i++) {
console.log("doing something");
}
jQuery("#modalDiv").hide(5000);
});
答案 1 :(得分:3)
有些浏览器会等到javascript线程完成执行,然后才会通过对DOM进行更改来更新屏幕。如果在javascript中对DOM进行了多次更改,那么这是更高效的处理方式,因为它可以解决一次问题并且只在屏幕上显示一次。这种行为的细节在/不同浏览器之间会有所不同,因为它是性能优化,并且一旦JS执行完毕,它们都会以相同的最终结果结束。
有一些技巧可以强制浏览器通过请求需要布局为最新的DOM属性来更新屏幕。您可以阅读有关如何触发重排/重绘的文章:http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/和其他相关文章:http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html。
例如,您应该可以使用此强制重排(将调用添加到.offset()
):
jQuery("#modalDiv").show().offset();
//This part takes up to a few seconds to execute and blocks the browser
for(var i = 0; i < 10000; i++){
console.log("doing something");
}
jQuery("#modalDiv").hide();
让屏幕更新的另一件事是在setTimeout()
上运行部分代码,因为这样可以让你的javascript的第一部分真正完成执行(因此屏幕将会更新)。这实际上并不像在代码示例中那样同步运行所有内容,但有时是一种正常的解决方法。
答案 2 :(得分:2)
您是否等待加载DOM?
尝试:
$(document).ready([your_function_here]);
如果文档对象模型(DOM)尚未加载,您将无法对其执行操作。
答案 3 :(得分:1)
使用setTimeout(func, 0)
异步运行代码(0表示立即运行该函数),因此它不会阻止浏览器
jQuery("#modalDiv").show();
setTimeout( function() {
//This part takes up to a few seconds to execute and blocks the browser
for(var i = 0; i < 10000; i++){
console.log("doing something");
}
jQuery("#modalDiv").hide();
}, 0);