如何使用JS立即应用DOM修改?

时间:2019-05-05 11:50:14

标签: javascript dom delay

我有一个Javascript函数,需要一点时间来处理。在执行此JS函数期间,我将显示一些文本(和/或应用模式覆盖),然后在执行后在页面上显示结果。碰巧只显示了最终文本,而没有显示该过程中的所有文本修改。 因此,基本上的问题是:为什么只有最后的DOM修改是可见/应用的,而其他所有先前的修改却没有? 跟随一个小例子简单地解释我的意思。

<!DOCTYPE html>
<html>
    <head>
        <style>
            #modal-overlay{position: absolute;left: 0; top: 0; right: 0; bottom: 0;z-index: 2;background-color: rgba(255,255,255,0.7);}
            #modal-overlay-content {position: absolute; transform: translateY(-50%); -webkit-transform: translateY(-50%); -ms-transform: translateY(-50%); top: 50%; left: 0; right: 0; text-align: center;}
        </style>
        <script>
            function test() {
                step1();
                step2();
                step3();
            }

            function step1() {
                document.getElementById("modal-overlay").style.display = "inline";
                document.getElementById("paragraph").innerText = "Do you see this text?";
            }

            function step2() {
                // do nothing for 5000ms
                var now = new Date().getTime();
                while (new Date().getTime() < now + 5000) { /* do nothing */ }
            }

            function step3() {
                document.getElementById("modal-overlay").style.display = "none";
                document.getElementById("paragraph").innerText = "Only this text is shown at the end of the process";
            }
        </script>
    </head>
    <body>
        <div id="modal-overlay" style="display: none;"><div id="modal-overlay-content"><h1>Loading...</h1></div></div>
        <p id="paragraph"></p>
        <input type="submit" value="Push" onclick="test()" />
    </body>
</html>

2 个答案:

答案 0 :(得分:0)

您应该使用setTimeout安排功能,而不要忙于等待。

function test() {
    step1();
    setTimeout(step3,5000)
}

function step1() {
    document.getElementById("modal-overlay").style.display = "inline";
    document.getElementById("paragraph").innerText = "Do you see this text?";
}

function step3() {
    document.getElementById("modal-overlay").style.display = "none";
    document.getElementById("paragraph").innerText = "Only this text is shown at the end of the process";
}
<html>
    <head>
        <style>
            #modal-overlay{position: absolute;left: 0; top: 0; right: 0; bottom: 0;z-index: 2;background-color: rgba(255,255,255,0.7);}
            #modal-overlay-content {position: absolute; transform: translateY(-50%); -webkit-transform: translateY(-50%); -ms-transform: translateY(-50%); top: 50%; left: 0; right: 0; text-align: center;}
        </style>
        <script>

        </script>
    </head>
    <body>
        <div id="modal-overlay" style="display: none;"><div id="modal-overlay-content"><h1>Loading...</h1></div></div>
        <p id="paragraph"></p>
        <input type="submit" value="Push" onclick="test()" />
    </body>
</html>


假设您有充分的理由,请不要使用固定工期加载方式。加载资源,并为完成注册一个回调。

答案 1 :(得分:0)

做你想要做的正确方法如下:

__init__

区别在于function test() { step1(); setTimeout(step3, 5000); } function step1() { document.getElementById("modal-overlay").style.display = "inline"; document.getElementById("paragraph").innerText = "Do you see this text?"; } function step3() { document.getElementById("modal-overlay").style.display = "none"; document.getElementById("paragraph").innerText = "Only this text is shown at the end of the process"; } 是“异步的”。它允许其他代码继续运行,并在经过所需的时间间隔后返回执行您为其提供的功能(此处为setTimeout)。

您的原始版本尝试以“同步”方式“等待” 5秒钟-通过基本上强迫代码执行空循环,并在每次迭代中检查时间戳,直到经过足够的时间为止。在这段时间内,代码正在执行-本身没有明显效果的代码,但是仍在执行代码。由于Javascript是单线程的,因此可以阻止该页面上发生的任何其他事情。特别是,它阻止了DOM更新的发生,这就是为什么您的代码未按预期运行的原因。

尽管如此,更严重的是,它根本阻止了用户与浏览器进行交互-无论他们是试图单击某些内容,滚动页面还是进行其他操作,浏览器似乎都完全没有响应。这就是为什么您应该始终对此类事件使用异步函数,而不是创建人为的循环来阻止任何事情发生的主要原因。