我遇到过DOM操作仅在浏览器运行所有迭代时生效的问题,即for,for,-loops。
示例:
var text = document.getElementById("text");
for (var i = 0; i < 100000000; i++) {
if (i % 1000000 == 0) {
setTimeout(function() {
text.innerHTML += "|";
}, 0);
}
}
&#13;
<p id="text"></p>
&#13;
我希望看到一个进度条行为,而只有在他运行for循环时才会操纵DOM。
我尝试使用setTimeout进行异步方法但没有成功。
有没有很好的方法来实现这个目标?
答案 0 :(得分:1)
使用类似的Javascript工具setTimeout
,而不是使用循环和setInterval
。这将每N毫秒重复运行一个函数。您可以使用计数器变量来跟踪何时添加进度条以及何时停止! http://jsfiddle.net/4odd386e/
var text = document.getElementById("text");
var i = 0;
function addOne() {
i += 1;
if (i % 10 === 0) {
text.innerHTML += "|";
}
if (i === 1000) {
// Progress complete
clearInterval(initProgress);
}
}
var initProgress = setInterval(addOne, 0);
此外,您最初使用的高数字导致进度非常缓慢,因此我使用10和1000作为示例。此代码可以使用更高的数字,但显示结果需要很长时间。
答案 1 :(得分:0)
将超时从0
更改为500
,您会看到它进展:
var text = document.getElementById("text");
for (var i = 0; i < 100000000; i++) {
if (i % 1000000 == 0) {
setTimeout(function() {
text.innerHTML += "|";
}, 500);
}
}
<p id="text"></p>
但是,程序在进入空闲状态以处理第一个计时器之前必须完成计数到1亿。
这是一种替代方法,它不会占用如此多的计算机资源:
var text = document.getElementById("text");
for (var i = 0; i < 100; i++) {
setTimeout(function() {
text.innerHTML += "|";
}, 10*i);
}
<p id="text"></p>
答案 2 :(得分:0)
由于Javascript在单个线程中运行,因此在完成处理计算之前,所有内容都会被阻止。
为了进行非阻塞计算,您可以使用webworkers并在worker调度postMessage
事件时更新dom。
示例:强>
主要代码:
var text = document.getElementById("text");
var myWorker = new Worker("js/forloop.js");
myWorker.postMessage(2000);
myWorker.onmessage = function(e) {
//e.data is an object which is passed from the worker
if (e.data === true)
text.innerHTML += "|";
}
WebWorker代码:
onmessage = function(e) {
for (var i = 0; i < e.data; i++) {
postMessage(true);
}
}
进一步阅读:Webworkers