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

All I can really suggest is getting a reference to the nodeHolder element outside of the 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);
 }

Or perhaps using a document fragment to hold the interim changes/appends and then add that to to the nodeHolder after the loop:

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 showing both approaches (with timing if the console is available).

于 2012-11-01T05:34:15.630 に答える
2

jQuery way...

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

Or javascript inside html...

<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

@David Thomas の提案に従って、必ず DocumentFragment を使用する必要があります。私が見た中で最も効率的なバージョンはこれです...必要に応じて浅いコピーと深いコピーを切り替えます(それでも createEl よりも高速ですcloneNode)。createElement

それが大きな利益をもたらすというわけではありませんが、できる限り割り当てを避けるべきです. 必要な場合にのみ変数にデータを格納します。もちろん、読みやすさに関しては別のことです。

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);

を追加すると、以前のコードでは 1000 個のフローがトリガーされるのに対し、1 つのフローのみがトリガーされるように、すべての子が子として追加さfragmentれることに注意してください。nodeHolderfragmentnodeHolder

参考:JavaScriptの高速化

于 2012-11-01T06:43:26.463 に答える
1

要約すれば:

  1. DOM セレクターをキャッシュします。
  2. for ループを捨てて、逆の while ループに進みます。
  3. 要素を DOM に追加するのは 1 回だけです。ほとんどの場合、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/

逆ループ速度参照: 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

Maybe: You could generate a HTML String in the for loop like:

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

and then set the .innerHTML property of nodeHolder to this string after the whole loop is completed.

(... and let the DOM renderer figure out how to best optimize the action)

于 2012-11-01T05:33:42.787 に答える
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 に答える