Javascript:如何在onClick完成之前更新页面

Javascript: how to update page before onClick is complete?

本文关键字:更新 onClick Javascript      更新时间:2023-09-26

我有一个用于解析20MB XML文件的函数。它工作得很好,但我想在几分钟内给出一些进度指示。

但是,这不起作用:

<head>
<script type="text/javascript">
function pauseJS(timeInMilliS) {
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < timeInMilliS);
}
function process() {
    for (var i = 0; i<=10; i++) {
        document.images["bar"].width += 5;
        document.images["bar"].height = 5;      
        pauseJS(500);
    }
}
</script>
</head>
<body>
    <input type="button" value="Go" onClick="process()"> 
    <img src="black.gif" name="bar" width=1 height=5 />
</body>

(pauseJS代表处理)进度条只会在处理完成时更新,而不会在处理过程中更新。

我看到一个类似的问题,但setTimeout似乎没有帮助在这种情况下

setTimeout正是处理这个问题的方法,但是您必须正确地构建解析函数。您想要做的最后一件事情是pauseJS中显示的忙碌等待。这不会暂停JavaScript,而是让JavaScript疯狂地运行,直到时间到达,或者浏览器因脚本消耗过多而取消脚本。: -)

为了让浏览器有时间更新页面显示,您必须让JavaScript线程返回给浏览器。例如,下面这个不行:

var TOTAL = 10000000;
var BATCH = 10000;
function doSomething() {
    for (n = 0; n < TOTAL; ++n) {
        if ((n % BATCH) == 0) {
            // ...change progress indicator...
        }
        // ...do processing...
    }
}

…因为它从不屈服。另一方面,这是有效的:

var TOTAL = 10000000;
var BATCH = 10000;
function doSomething() {
    var n = 0;
    work();
    function work() {
        var maxn = Math.min(n + BATCH, TOTAL);
        for ( ; n < maxn; ++n) {
            // ...do processing...
        }
        // ...update progress indicator...
        if (n < TOTAL) {
            setTimeout(work, 0);
        }
    }
}

正如您所看到的,这里我们将工作分解成离散的批次,并定期停止,安排下一批工作,并将控制权返回给浏览器。这给了它更新页面的时间,之后它会回叫我们(不是在0毫秒之后,而是在下一次可以的时候,这通常是更新自己所需要的5-10毫秒)。

Javascript只有一个线程,这意味着你不可能一次做多件事。

您必须分解XML处理函数,以便它完成大块工作,更新进度条,等等。