64

ドキュメント フラグメントへの追加innerHTMLが最近議論されていることは知っていますが、DOM 標準に含まれることを期待しています。しかし、その間に使用することになっている回避策は何ですか?

つまり、取る

var html = '<div>x</div><span>y</span>';
var frag = document.createDocumentFragment();

簡単なワンライナーで、 の とdiv内部spanの両方が必要です。frag

ループなしのボーナスポイント。jQueryは許可されていますが、私はすでに試しました$(html).appendTo(frag); fragその後も空です。

4

11 に答える 11

101

ループなしの最新のブラウザーでの方法は次のとおりです。

var temp = document.createElement('template');
temp.innerHTML = '<div>x</div><span>y</span>';

var frag = temp.content;

または、再利用可能なものとして

function fragmentFromString(strHTML) {
    var temp = document.createElement('template');
    temp.innerHTML = strHTML;
    return temp.content;
}

更新:ピートの主なアイデアを使用するより簡単な方法を見つけました。これは、IE11 をミックスに追加します。

function fragmentFromString(strHTML) {
    return document.createRange().createContextualFragment(strHTML);
}

カバレッジはメソッドよりも優れており<template>、IE11、Ch、FF で問題なくテストされています。

ライブ テスト/デモが利用可能http://pagedemos.com/str2fragment/

于 2014-08-09T00:36:48.153 に答える
23

現在、文字列のみを使用してドキュメント フラグメントを埋める唯一の方法は、一時オブジェクトを作成し、子をループしてフラグメントに追加することです。

  • ドキュメントに追加されないため、何もレンダリングされないため、パフォーマンスに影響はありません。
  • ループが表示されますが、最初の子をループしているだけです。ほとんどのドキュメントにはいくつかのセミルート要素しかないので、それも大したことではありません。

ドキュメント全体を作成したい場合は、代わりに DOMParser を使用してください。この回答をご覧ください。

コード:

var frag = document.createDocumentFragment(),
    tmp = document.createElement('body'), child;
tmp.innerHTML = '<div>x</div><span>y</span>';
while (child = tmp.firstElementChild) {
    frag.appendChild(child);
}

ワンライナー (読みやすくするために 2 行) (入力: String html、出力: DocumentFragment frag):

var frag =document.createDocumentFragment(), t=document.createElement('body'), c;
t.innerHTML = html; while(c=t.firstElementChild) frag.appendChild(c);
于 2012-02-14T22:17:38.743 に答える
12

Range.createContextualFragmentを使用します。

var html = '<div>x</div><span>y</span>';
var range = document.createRange();
// or whatever context the fragment is to be evaluated in.
var parseContext = document.body; 
range.selectNodeContents(parseContext);
var fragment = range.createContextualFragment(html);

このアプローチとアプローチの主な違いは次の<template>とおりです。

  • Range.createContextualFragment は、もう少し広くサポートされています (IE11 でサポートされたばかりで、Safari、Chrome、および FF ではしばらくサポートされていました)。

  • HTML 内のカスタム要素は範囲を使用してすぐにアップグレードされますが、テンプレートを使用して実際のドキュメントに複製された場合のみです。テンプレート アプローチはもう少し「不活性」であり、これが望ましい場合があります。

于 2014-08-10T05:56:32.580 に答える
4

@PAEz は、@RobW のアプローチには要素にテキストが含まれていないことを指摘しました。これは、 NodesではなくElementschildrenのみを取得するためです。より堅牢なアプローチは次のようになります。

var fragment = document.createDocumentFragment(),
    intermediateContainer = document.createElement('div');

intermediateContainer.innerHTML = "Wubba<div>Lubba</div>Dub<span>Dub</span>";

while (intermediateContainer.childNodes.length > 0) {
    fragment.appendChild(intermediateContainer.childNodes[0]);
}

HTML の大きなチャンクではパフォーマンスが低下する可能性がありますが、多くの古いブラウザと互換性があり、簡潔です。

于 2016-05-16T17:56:23.643 に答える
3

createDocumentFragment は、空の DOM「コンテナ」を作成します。innerHtml およびその他のメソッドは (コンテナーではなく) DOM ノードでのみ機能するため、最初にノードを作成してからフラグメントに追加する必要があります。appendChild の面倒なメソッドを使用してそれを行うか、1 つのノードを作成してその innerHtml を変更し、それをフラグメントに追加することができます。

var frag = document.createDocumentFragment();
    var html = '<div>x</div><span>y</span>';
var holder = document.createElement("div")
holder.innerHTML = html
frag.appendChild(holder)

jquery を使用すると、html を文字列として保持して構築するだけです。それをjqueryオブジェクトに変換してjqueryのような操作を実行したい場合は、メモリ内にjqueryオブジェクトを作成する$(html)を実行するだけです。追加する準備ができたら、ページ上の既存の要素に追加するだけです

于 2012-02-14T21:59:29.680 に答える
-1

できるだけ少ない行でこれを行うには、上のコンテンツを別の div でラップして、appendchild を複数回ループまたは呼び出す必要がないようにすることができます。jQueryを使用すると(前述のように許可されています)、接続されていないdomノードを非常に迅速に作成してフラグメントに配置できます。

var html = '<div id="main"><div>x</div><span>y</span></div>';
var frag = document.createDocumentFragment();
frag.appendChild($​(html)[0]);
于 2012-02-14T21:59:06.163 に答える