1

我想知道如何使下面的循环更有效。在我的页面上,它的迭代次数超过了 100,这就是为什么,你可以想象它很麻烦。

    for (var i = 0; i < 1000; i += 1) {
        var el = document.createElement('div');
        el.appendChild(document.createTextNode('Node ' + (i + 1)));
        document.getElementById('nodeHolder').appendChild(el);
    }

提前感谢您的帮助。

4

6 回答 6

3

我真正能建议的是获取nodeHolder对 for 之外的元素的引用:

var nodeHolder = document.getElementById('nodeHolder');

 for (var i = 0; i < 1000; i += 1) {
    var el = document.createElement('div'); 
el.appendChild(document.createTextNode('Node ' + (i + 1)));
    nodeHolder.appendChild(el);
 }

或者也许使用文档片段来保存临时更改/附加,然后在循环后将其添加到 nodeHolder:

var fragment = document.createDocumentFragment();

for (var i = 0; i < 1000; i += 1) {
    var el = document.createElement('div'); 
    el.appendChild(document.createTextNode('Node ' + (i + 1)));
    fragment.appendChild(el);
}

document.getElementById('nodeHolder').appendChild(fragment.cloneNode(true));

JS Fiddle 显示了这两种方法(如果控制台可用,则显示时间)。

于 2012-11-01T05:34:15.630 回答
2

jQuery的方式...

var d = '';
for(var i=0;i<1000;i++) d += '<div>Node ' + (i + 1) + '</div>';
$('#nodeHolder').append(d);

或者html里面的javascript...

<div id="nodeHolder">
<script>(function() { for(var i=0;i<1000;i++) document.write('<div>Node ' + (i + 1) + '</div>'); })();</script>
</div>
于 2012-11-01T05:33:47.860 回答
1

也许:您可以在 for 循环中生成一个 HTML 字符串,例如:

<div>Node 1</div><div>Node 2</div>

然后在整个循环完成后将nodeHolder的.innerHTML属性设置为这个字符串。

(...让 DOM 渲染器弄清楚如何最好地优化动作)

于 2012-11-01T05:33:42.787 回答
1

总之:

  1. 缓存你的 DOM 选择器。
  2. 放弃 for 循环,然后进行反向 while 循环。
  3. 只将元素附加到 DOM 一次。DOM 几乎总是瓶颈。

在此模式中,您可以利用反向循环:

//Cache the DOM element
var node = document.getElementById('nodeHolder'),
    markup = [];

//Run the loop backwards for additional speed
var i = 10000;
while(i--){
  markup.push('<div>Node ' + (i + 1) + '</div>');
}

//Reverse the array, join it, then set the innerHTML
node.innerHTML = markup.reverse().join('');​

工作示例:http: //jsfiddle.net/ZAkMZ/3/

反向while循环速度参考:https ://blogs.oracle.com/greimer/entry/best_way_to_code_a

jQuery版本:

//Cache the DOM element
var node = $('#nodeHolder'),
    markup = [];

//Run the loop backwards for additional speed
var i = 10000;
while(i--){
  markup.push('<div>Node ' + (i + 1) + '</div>');
}

//Reverse the array, join it, then set the innerHTML
node.append(markup.reverse().join(''));​
于 2012-11-01T05:53:58.347 回答
1

您肯定需要按照@David Thomas 的建议使用 DocumentFragment。我看到的最有效的版本是 this...cloneNode总是比根据需要createElement在浅拷贝或深拷贝之间切换(仍然比 createEl 快)要好。

并不是说它会带来显着的收益,但您应该尽可能回避作业。仅在需要时将数据存储在变量中。当然,在可读性方面,它是另一回事。

var fragment = document.createDocumentFragment();
var tplEl = document.createElement('div');
var contentTpl = document.createTextNode('Node ');

for (var i = 1; i <= 1000; i++) {
    var curNode = contentTpl.cloneNode(false);
    curNode.nodeValue = curNode.nodeValue + i;
    tplEl.cloneNode(false).appendChild(curNode);
    fragment.appendChild(tplEl);
}

document.getElementById('nodeHolder').appendChild(fragment);

请注意,添加fragmentnodeHolder添加所有子级fragment作为子级nodeHolder仅触发 1 个流,而不是之前代码中的 1000 个流。

参考:加速 JavaScript

于 2012-11-01T06:43:26.463 回答
0

可能是这样的:

for (var i = 0; i < 100; i+=1) {
  $("<div/>").appendTo("body").attr({"class":'txtHolder'});
  $(".txtHolder").append(i+1);            

}​</p>

于 2012-11-01T06:01:41.430 回答