如何使用" Stop Scripting Dialog"来呈现此内容。任何解决方案都可以理解。提前致谢
document.write("<ul>");
for(var i=0;i<1000000;i++){
document.write("<li>");
document.write("<div><input value='"+i+"'/></div>");
document.write("</li>");
}
document.write("</ul>");
答案 0 :(得分:5)
首先,我将假设这是一个理论上的讨论,因为没有页面设计应该考虑数百万个DOM元素。如果有人认为可能有这么多元素,那么应该制定一个不同的设计,一次显示数据的小窗口。
要绕过无响应的对话框,您必须将javascript进程分解为多个部分并分别执行每个部分,同时允许系统处理部分之间的其他事件。这通常是通过将工作分成块然后在setTimeout()
上执行每个块来完成的。您可以在此处看到几个处理大型数组的示例:
Best way to iterate over an array without blocking the UI
但是,此测试存在许多问题,因为您还必须停止使用document.write()
,因为一旦您让系统处理setTimeout()
操作之间的其他事件,您就不能再使用document.write()
在解析流中插入新元素,因为文档将完成解析。相反,您必须更改为在DOM中的适当位置动态插入DOM元素。
以下是一些代码:
function insertElements(num) {
var totalCntr = 0;
var chunkSize = 1000;
var parent = document.getElementById("container");
var progress = document.getElementById("progressCntr");
function doChunk() {
var chunkCntr = 0;
var fragment = document.createDocumentFragment();
while (chunkCntr < chunkSize && totalCntr < num) {
var li = document.createElement("li");
li.innerHTML = "<div><input value='" + totalCntr + "'/></div>";
fragment.appendChild(li);
++totalCntr;
++chunkCntr;
}
parent.appendChild(fragment);
progress.innerHTML = totalCntr;
if (totalCntr < num) {
setTimeout(doChunk, 0);
}
}
// start the whole thing
doChunk();
}
insertElements(100000);
工作演示:http://jsfiddle.net/jfriend00/0vw82q5y/
目前设置为100,000个元素。如果您想尝试更高的值,欢迎(根据系统的内存限制)。
如果您降低chunkSize
值,系统将在运行时更加响应用户输入。如果您增加chunksize
值,整个端到端时间可能会更快。
如果每个块都可以是它自己的DOM树,那么它可以插入到一个单独的DOM操作中,那么这里的端到端时间会更快。如果您插入了所有<li>
元素,那么这是不可能的。这里使用文档片段试图帮助解决这个问题,但最后,它仍然必须将每个<li>
插入到它自己的文档中,这确实会减慢这个操作。
注意:将工作分解为块可能会降低整体端到端性能。我没有尝试优化此代码的性能,而是想说明这个概念。
答案 1 :(得分:0)
当javascript更新DOM对象时,浏览器必须再次呈现页面;在你的情况下,它将是100万次。这保证即使是最快的机器也会减速。
通过生成HTML尽可能多的时间来避免这种情况,但只要求浏览器渲染一次。
var list;
for (var i = 0; i < 1000000; i++) {
list += "<li><div><input value='" + i + "'/></div></li>";
}
document.write("<ul>"+list+"</ul>");