JavaScript执行期间无响应的浏览器

时间:2015-10-28 13:58:55

标签: javascript browser

我必须使用纯JavaScript显示进度条/状态指示器,请不要使用jQuery 我的代码是:

<script type="text/javascript">
function processObjects()
{
    var selectedRows = {}; // array of selected rows from table
    var count = selectedRows.length; // count value exceeds 100
    var myDiv = document.getElementById("myDiv");
    for(var i=0; i < count; i++)
    {
        myDiv.innerHTML = (i+1)+"/"+count;
        // Process each object from array
        // no Ajax call
        // takes almost 0.1 sec for each object <- this is not an issue
    }
}
</script>

<div id="myDiv"></div>
<input type="button" onclick="processObjects()" value="Process Objects" />
<table>
    <!-- Table with lots of rows with checkboxs -->
</table>

问题:

当我在任何浏览器中运行此脚本时,页面变得无响应,并且不会使用innerHTML更新状态为1/100 ... 2/100 ... 3/100,如此。

什么可能是阻止浏览器无法响应的可能解决方案?

2 个答案:

答案 0 :(得分:3)

JS是单线程的,它必须在函数内部时充分注意浏览器。

如果您需要在处理某些内容时让浏览器有机会呼吸,则需要通过setTimeout()函数调用长进程。

在以下示例中查看我是如何做到的:

function doProgress(count) {

    if (count == 100)
       return;

    document.getElementById("myDiv").innerHTML = count;
    count++;

    setTimeout(doProgress, 0, count);   //<- calling the same function with new count here. "0" is the milliseconds to call it after. "count" is the argument to pass

}

它只展示了这种技术,掌握了很多最佳实践。

答案 1 :(得分:1)

Javascript在代码执行时锁定视图(除非您使用画布),因此您必须在能够在DOM中查看结果之前结束代码的执行。
即使这篇文章是关于角度的,这个介绍很好地解释了javascript的工作原理以及冻结浏览器的原因http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

如果你想保持简单,你可以这样做:

<script type="text/javascript">
    var start=0;
    var selectedRows = {}; // array of selected rows from table
    var count = selectedRows.length; // count value exceeds 100 value
    var myDiv = document.getElementById("myDiv");

function processObject(){
    myDiv.innerHTML = (++start)+"/"+count;
    // Process one object from array using "start" as index
    if(start<count){
        setTimeout(processObject, 100);
    }
}
function processObjects(){
    //eventually update values
    selectedRows=[] //adds items to array
    count = selectedRows.length;
    myDiv = document.getElementById("myDiv");
    processObject();
}
</script>

<div id="myDiv"></div>
<input type="button" onclick="processObjects()" value="Process Objects" />
<table>
    <!-- Table with lots of rows with checkboxs -->
</table>

如果您不想使用全局变量,可以执行以下操作:

function processObject(){
    processObject.myDiv.innerHTML = (++processObject.start)+"/"+processObject.count;
    // Process one object from array using "start" as index
    if(processObject.start<processObject.count){
        setTimeout(processObject, 100);
    }
}
function processObjects(){
    processObject.selectedRows=[]; //array with rows to process 
    processObject.count=processObject.selectedRows.length
    processObject.start=0;
    processObject.myDiv=document.getElementById("myDiv");
    processObject();
}