Cordova 在长时间 Javascript 期间冻结 UI 而

Cordova freeze UI during long Javascript while

我无法创建工作示例,但代码很简单。


配置

IDE: Visual studio 2017

目标平台: Windows x64

系统: Win 10

我的项目: Javascript // 空白应用程序 (Apache Cordova) // 版本。 6.3.1


HTML // index.html

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <header></header>
        <main>
            <div id="cal">

            </div>
        </main>
        <footer>
            <!-- ## this creates a simple pure css loader ## -->
            <div class="progress">
                <div class="indeterminate"></div>
            </div>
            <a href="#" class=".addItem">Add</a>
        </footer>

        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="scripts/platformOverrides.js"></script>

        <script src="frameworks/jquery-3.2.1.min.js"></script>
        <script src="frameworks/materialize/js/materialize.min.js"></script>        

        <script type="text/javascript" src="scripts/index.js"></script>

    </body>
</html>

Javascript // index.js

(function () {
    "use strict";


    document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );

    function onDeviceReady() {

        $(document).ready(function () {
            $('.addItem').on('click', function () {
                setTimeout(function () {
                    loadCalendar();
                }, 5000);
            });

        });

    };


    function loadCalendar() {
        var i=0;
        while (i <= 10000) {
            var html = '<div class="row"></div>';
            $('#cal').append(html);
            i++;
        }
    }


} )();

应用程序启动并且 UI 按预期工作,progress 加载程序显示他的 css 动画。单击按钮 addItem 后全部工作 5 秒,然后 UI 冻结直到 while loop 结束。我觉得不正常,怎么解决?

谢谢

编辑

重要说明

我不希望在循环中更新DOM,上面这段代码不是真正的代码,它只是用于理解和测试。真正的循环要短得多,快得多,但仍然是个问题。

发生的情况是整个界面冻结,整个应用程序。 CSS 动画应该完全独立于 Javascript,但是它会卡住!

Here an example of what I expected

我希望这能更好地阐明这一点。

我认为这是意料之中的。您拨打

$('#cal').append(html)
10,001 次。每次执行此操作时,您都在修改 DOM,这是一项昂贵的操作。

如果你真的需要写出 10001 div class='row' 个元素,你最好将它们全部写入一个字符串,然后再进行一个追加。它仍然不理想,但如果不了解您要实现的目标,就很难找到更好的解决方案。

function loadCalendar() {
    var i=0;
    var html = '';
    while (i <= 10000) {
        html += '<div class="row"></div>';
        i++;
    }
    $('#cal').append(html);
}

如评论中所述,所有循环声明都是阻塞程序,在循环完成之前-即使是最微不足道的悬停效果也无法响应。

JavaScript是线性的、同步的、单线程的进程。要避免冻结情况,您需要将循环操作移至单独的线程。

例如:在另一个文档的单独实例上!