我必须使用纯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,如此。
什么可能是阻止浏览器无法响应的可能解决方案?
答案 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();
}