我想用AJAX打印很多数字。
这样的事情:(每个新行都是前一行的更新!)
output is:
1
12
123
1234
12345
123456
...
我经常尝试并阅读了很多同样的问题,但我找不到合适的答案。
真正的问题是javascript中的每个FOR LOOP在END循环后都不会影响DOM。我只想在长时间运行的工作中更新FOR LOOP中的DOM。
请查看我的代码。
$("#btn").on("click", dowork);
function dowork() {
document.getElementById("foo").innerHTML = "working";
setTimeout(function() {
var counter = 100; // i want assign counter = 2000000000
for (var i = 0; i < counter; i++) {
document.getElementById("print_here").innerHTML += i;
}
document.getElementById("foo").innerHTML = "done!";
}, 50);
}
#btn {
background: #1f1f1f;
padding: 10px;
font-weight: bolder;
color: #fff;
width: 50%;
margin: auto;
margin-top: 10px;
text-align: center;
cursor: pointer;
}
#print_here {
overflow-wrap: break-word;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="btn">CLICK TO DO WORK</div>
<div id="foo"></div>
<div id="print_here"></div>
感谢您解决此问题的任何答案和帮助。
答案 0 :(得分:4)
您的DOM在更新时被“锁定”,并且重新绘制了循环完成的DOM。您可以释放资源,让DOM每次更新时都会更新DOM setTimeout
,类似于:
setTimeout(function(){
document.getElementById("print_here").innerHTML += i;
},1);
确保setTimeout
使用i
使用let i
代替var i
$("#btn").on("click", dowork);
function dowork() {
document.getElementById("foo").innerHTML = "working";
var counter = 3000; // i want assign counter = 2000000000
for (let i = 0; i < counter; i++) {
setTimeout(function() {
document.getElementById("print_here").innerHTML += i;
}, 1);
}
document.getElementById("foo").innerHTML = "done!";
}
#btn {
background: #1f1f1f;
padding: 10px;
font-weight: bolder;
color: #fff;
width: 50%;
margin: auto;
margin-top: 10px;
text-align: center;
cursor: pointer;
}
#print_here {
overflow-wrap: break-word;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="btn">CLICK TO DO WORK</div>
<div id="foo"></div>
<div id="print_here"></div>
我想把#foo改成“完成!”在FOR语句结束后
您可以检查自己是否在setTimeout
内处理的最后一个项目,类似于:
if (i == counter - 1){
document.getElementById("foo").innerHTML = "done!";
}
$("#btn").on("click", dowork);
function dowork() {
document.getElementById("foo").innerHTML = "working";
var counter = 3000; // i want assign counter = 2000000000
for (let i = 0; i < counter; i++) {
setTimeout(function() {
document.getElementById("print_here").innerHTML += i;
if (i == counter - 1){
document.getElementById("foo").innerHTML = "done!";
}
}, 1);
}
}
#btn {
background: #1f1f1f;
padding: 10px;
font-weight: bolder;
color: #fff;
width: 50%;
margin: auto;
margin-top: 10px;
text-align: center;
cursor: pointer;
}
#print_here {
overflow-wrap: break-word;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="btn">CLICK TO DO WORK</div>
<div id="foo"></div>
<div id="print_here"></div>
答案 1 :(得分:1)
您需要让调用堆栈完成,以便浏览器可以在页面上完成其工作。如果您陷入一个主线程,则不会发生页面更新。
执行此操作的一种方法是使用setImmediate或nextTick。这是非标准的,因此请检查此polyfill:https://www.npmjs.com/package/browser-next-tick
基本上,你做一个迭代,然后告诉浏览器尽快进行下一次迭代......这发生在一个新的调用堆栈上。
答案 2 :(得分:-2)
以下是您的工作代码:
#btn {
background: #1f1f1f;
padding: 10px;
font-weight: bolder;
color: #fff;
width: 50%;
margin: auto;
margin-top: 10px;
text-align: center;
cursor: pointer;
}
#print_here {
overflow-wrap: break-word;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="btn">CLICK TO DO WORK</div>
<div id="foo"></div>
<div id="print_here"></div>
{{1}}
行是您要打印的行数。