在阻止代码之前和之后做一些事情

时间:2013-07-10 16:54:58

标签: javascript jquery

原谅我糟糕的头衔,但是现在,我甚至不知道我不知道的事情。

如果我的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”的元素永远不会显示在页面上。我不是要解决这个“问题”,我只是想了解幕后发生的事情,导致我的脚本表现得像它一样。

4 个答案:

答案 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);
});

DEMO

答案 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);