21

大量の HTML を挿入する方法について、このような嫌な思いをしました。私たちが得たと仮定しましょう:

var html="<table>..<a-lot-of-other-tags />..</table>"

そして私はこれを入れたい

$("#mydiv")

以前は次のようなことをしました

var html_obj = $(html); $("#mydiv").append(html_obj);

htmljQuery が解析して DOM-Objects を作成するのは正しいですか? さて、これは私がどこかで読んだものです(UPDATE:私が読んだことを意味しました.jQueryはhtmlを解析してDOMツリー全体を手動で作成します-そのナンセンスですよね?!、コードを変更しました:

$("#mydiv").attr("innerHTML", $("#mydiv").attr("innerHTML") + html);

より速く感じますね。そして、これが次と同等であることは正しいですか:

document.getElementById("mydiv").innerHTML += html? それとも、jquery がバックグラウンドで追加の高価なことを行っているのでしょうか?

代替案も学びたいです。

4

8 に答える 8

33

次のことを試してください。

$("#mydiv").append(html);

受け入れられた回答を含む他の回答は、2〜10遅くなりますjsperf

受け入れられた回答は、 IE のバグが原因で要素を設定できないため、IE 6、7、および 8 では機能しません: jsbininnerHTML<table>

于 2010-12-12T09:57:58.297 に答える
22

innerHTML は非常に高速で、多くの場合、それを設定するだけで最良の結果が得られます (私は追加を使用します)。

ただし、「mydiv」にすでに多くのコンテンツがある場合は、ブラウザにそのすべてのコンテンツ (以前に存在していたすべてのコンテンツと新しいコンテンツのすべて) を再度解析してレンダリングするよう強制しています。 代わりに「mydiv」にドキュメント フラグメントを追加することで、これを回避できます。

var frag = document.createDocumentFragment();
frag.innerHTML = html;
$("#mydiv").append(frag);

このようにして、新しいコンテンツのみが解析され (避けられません)、既存のコンテンツは解析されません。

編集: 悪いことです... ドキュメント フラグメントでは innerHTML が十分にサポートされていないことがわかりました。どのノード タイプでも同じ手法を使用できます。あなたの例では、ルート テーブル ノードを作成し、それに innerHTML を挿入できます。

var frag = document.createElement('table');
frag.innerHTML = tableInnerHtml;
$("#mydiv").append(frag);
于 2008-09-22T22:22:32.137 に答える
9

何を避けようとしていますか?「嫌な予感」はとても漠然としています。「DOM は遅い」と聞いて「DOM を避ける」と決めた場合、これは不可能です。innerHTML を含め、コードをページに挿入するすべての方法で、DOM オブジェクトが作成されます。DOM は、ブラウザのメモリ内のドキュメントの表現です。DOM オブジェクトを作成したい

「DOM が遅い」と言われる理由は、要素を作成するdocument.createElement()ための公式の DOM インターフェイスである を使用した要素の作成が、一部のブラウザーで非標準の innerHTML プロパティを使用するよりも遅いためです。これは、DOM オブジェクトを作成することが悪いという意味ではありません。DOM オブジェクトを作成する必要があります。そうしないと、コードはまったく何もしません。

于 2008-09-22T21:17:01.687 に答える
2

アイテムを追加する最速の方法

DOMツリーに追加する最も速い方法は、すべての追加を単一のDOMフラグメントにバッファリングしてから、domフラグメントをdomに追加することです。

これは、私のゲームエンジンで使用する方法です。

//Returns a new Buffer object
function Buffer() {

    //the framgment
    var domFragment = document.createDocumentFragment();

    //Adds a node to the dom fragment
    function add(node) {
        domFragment.appendChild(node);
    }

    //Flushes the buffer to a node
    function flush(targetNode) {

        //if the target node is not given then use the body
        var targetNode = targetNode || document.body;

        //append the domFragment to the target
        targetNode.appendChild(domFragment);

    }

    //return the buffer
    return {
        "add": add,
        "flush": flush
    }
}


//to make a buffer do this
var buffer = Buffer();

//to add elements to the buffer do the following
buffer.add(someNode1);

//continue to add elements to the buffer
buffer.add(someNode2);
buffer.add(someNode3);
buffer.add(someNode4);
buffer.add(someN...);

//when you are done adding nodes flush the nodes to the containing div in the dom
buffer.flush(myContainerNode);

このオブジェクトを使用すると、Firefox4で1秒間に最大1000個のアイテムを画面に最大40回レンダリングできます。

これがユースケースです。

于 2011-06-10T03:44:44.373 に答える
2

DOM フラグメントの使用に関する答えは正しい方向にあります。DOM に常に挿入している html オブジェクトが多数ある場合は、フラグメントを使用すると速度が向上することがわかります。John Resig によるこの投稿は、それをかなりよく説明しています: http://ejohn.org/blog/dom-documentfragments/

于 2008-09-27T03:04:06.643 に答える
1

まず、各方法で 100 回または 1,000 回実行するのにかかる時間を計るスクリプトを作成します。

繰り返しが何らかの形で最適化されていないことを確認するには (私は JavaScript エンジンの専門家ではありません)、挿入する html を毎回変更します。テーブルのセル。

于 2008-09-22T21:16:27.413 に答える
0

で巨大な文字列を作成し、この文字列に jquery を追加します。私にとっては、うまく機能します。

于 2012-08-28T14:32:54.123 に答える
-1

あなたは代替案に興味があると言っています。DOM関連のjQueryプラグインのリストを見ると、プログラムでDOMツリーを生成するための専用のプラグインがいくつか見つかります。たとえば、SuperFlyDomまたはDOMElementsCreatorを参照してください。しかし、他にもあります。

于 2008-09-22T21:59:04.893 に答える