23

DOMに要素を追加するためのいくつかの異なる方法を見てきました。最も優勢なのは、たとえば、

document.getElementById('foo').innerHTML ='<p>Here is a brand new paragraph!</p>';

また

newElement = document.createElement('p');
elementText = document.createTextNode('Here is a brand new parahraph!');
newElement.appendChild(elementText);
document.getElementById('foo').appendChild(newElement);

しかし、どちらかを実行することの利点はわかりません。どちらか一方をもう一方に対して実行する必要がある場合の経験則はありますか、それともこれらの1つが完全に間違っているのでしょうか。

4

6 に答える 6

22

いくつかのメモ:

  • IEでの使用innerHTMLは高速ですが、chrome+firefoxでは低速です。これは、常に変化するs+ sのセットでこれを示す1つのベンチマークです。これは、一定の単純な場合にこれを示すベンチマークです。<div><p><table>

  • 一方、DOMメソッドは従来の標準innerHTMLであり(HTML5で標準化されています)、新しく作成された要素への参照を保持できるため、後で変更できます。

  • innerHTMLは高速(十分)で、簡潔で、使いやすいため、あらゆる状況でそれに頼りたくなります。innerHTMLただし、を使用すると、既存のすべてのDOMノードがドキュメントから切り離されることに注意してください。このページでテストできる例を次に示します。

    まず、ノードがページ上にあるかどうかをテストできる関数を作成しましょう。

    function contains(parent, descendant) {
        return Boolean(parent.compareDocumentPosition(descendant) & 16);
    }
    

    が含まれているtrue場合、これは返されます。次のようにテストします。parentdescendant

    var p = document.getElementById("portalLink")
    console.log(contains(document, p)); // true
    document.body.innerHTML += "<p>It's clobberin' time!</p>";
    console.log(contains(document, p)); // false
    p = document.getElementById("portalLink")
    console.log(contains(document, p)); // true
    

    これは印刷されます:

    true
    false
    true
    

    の使用が要素innerHTMLへの参照に影響を与えたようには見えないかもしれませんが、影響はあります。portalLink適切に使用するには、再度取得する必要があります。

于 2011-12-11T04:02:13.660 に答える
5

いくつかの違いがあります。

  1. innerHTMLHTML5用のW3Cによってのみ標準化されています。これは、人気のあるすべてのブラウザでデファクトスタンダードになっていますが、技術的にはHTML 4では、標準に準拠した開発者が使用して死んでしまうことは決してないベンダー拡張です。一方、それははるかに便利であり、実際にはすべてのブラウザでサポートされています。
  2. innerHTML 要素の現在のコンテンツを置き換えます(変更することはできません)。しかし、繰り返しになりますが、この制限を気にしないと便利になります。
  3. innerHTML はるかに高速であることが測定されています(確かに、そのテストには、現在広く使用されていない古いバージョンのブラウザが含まれます)。
  4. innerHTML適切にエンコードされていないユーザー指定の値に設定されている場合は、セキュリティリスク(XSS)を表す可能性があります(例el.innerHTML = '<script>...')。

上記に基づいて、実際的な結論は次のように思われます。

  • 少し制限があるという事実innerHTML(ターゲット要素をルートとするDOMサブツリーの完全な置換のみ)を気にせず、ユーザー提供のコンテンツを挿入することで脆弱性のリスクを冒さない場合は、それを使用してください。それ以外の場合は、DOMを使用してください。
于 2011-12-11T04:00:47.750 に答える
1

このベンチマークデータによるとinnerHTML、DOM要素を作成するよりもはるかに高速な結果を得ることができます。古いIEバージョンを使用する場合は特に明確です。

于 2011-12-11T04:00:49.510 に答える
1

これは古いスレッドですが、言及されていないことの1つは、しばらくの間innerHTMLは高速になる可能性があることです。注意が必要です。を使用innerHTMLすると、変更された要素のすべての子が、新旧を問わずレンダリングされます。そのため、1つのinnerHTML割り当てはDOMの作成/追加よりも(わずかに)高速ですが、複数の割り当てはinnerHTML明らかに遅くなります。

例えば:

for(let i=0; i < 10; i++)
   document.body.innerHTML+='<div>some text</div>';

約5倍遅くなります

let html = '';
for(let i=0; i < 10; i++)
   html += '<div>some text</div>';

document.body.innerHTML = html;

割り当てによりブラウザが要素をネイティブに作成/追加できるためinnerHTML、2番目のメソッドでは10個の要素がネイティブに作成/追加され、最初のメソッドでは55個の要素が作成/追加されます(45個が破棄されます)。最初のループで1つの要素が作成されます-反復、2番目のループで作成された2つの要素-反復(元の要素が破棄される)、3番目のループで作成された3つの要素-反復(前の2つが破棄される)など。

速度を上げるために使用する場合は、新しいDOMコンテナ/要素の作成など innerHTML、割り当てを行う前に、まずhtml文字列全体を作成する必要があります。一方、既存のchildNodeを持つコンテナ、特に多数のchildNodeを持つコンテナを追加すると、パフォーマンスが低下します。innerHTMLinnerHTML

于 2019-03-22T19:49:15.167 に答える
0

1つ目は単純明快で、読みやすく、コードが少なく、高速である可能性があります。
2つ目は、作成する要素をより細かく制御できるようにします。つまり、JSを使用して新しい要素を変更するのがはるかに簡単になります(イベントのアタッチや、コードでの使用など)。
2番目の方法は、「クリーンな」コードが好きな「純粋主義者」向けです(迅速で汚いものではありません)。
私は言います、両方を使用して、あなたにもっとよく合うものを見て、それに合わせてください。

于 2011-12-11T04:00:27.513 に答える
0

パフォーマンスの違いが極端でない限り、私は常に読みやすさを好みます。この1回限りのケースでは、おそらくわずかな違いになります。

このような1回限りのケースでは、innerHTMLプロパティの設定が最も読みやすくなります。

ただし、JavaScriptで多くのプログラムによるコンテンツ生成を行っている場合は、DOMオプションを読みやすく理解しやすくなります。

例:

innerHTMLこのコードを比較してください:

http://jsfiddle.net/P8m3K/1/

// Takes input of a value between 1 and 26, inclusive,
// and converts it to the appropriate character
function alphaToChar(alpha)
{
    return String.fromCharCode('a'.charCodeAt() + alpha - 1);
}

var content = "<ul>";
for(i = 0; i < 10; ++i)
{
    content += "<li>";
    for(j = 1; j <= 26; ++j)
    {
        content += "<a href=\"" + alphaToChar(j) + ".html\">"
            + alphaToChar(j)
            + "</a>";
    }
    content += "</li>";
}
document.getElementById("foo").innerHTML = content;

このDOMコードに:

http://jsfiddle.net/q6GB8/1/

// Takes input of a value between 1 and 26, inclusive,
// and converts it to the appropriate character
function alphaToChar(alpha)
{
    return String.fromCharCode('a'.charCodeAt() + alpha - 1);
}

var list = document.createElement("ul");
for(i = 0; i < 10; ++i)
{
    var item = document.createElement("li");
    for(j = 1; j <= 26; ++j)
    {
        var link = document.createElement("a");
        link.setAttribute("href", alphaToChar(j) + ".html");
        link.innerText = alphaToChar(j);
        item.appendChild(link);
    }
    list.appendChild(item);
}
document.getElementById("foo").appendChild(list);

このレベルでは、長さに関しては非常に似たものになり始めます。

ただし、DOMコードは保守が容易であり、終了タグを省略するなど、診断が難しいタイプミスや間違いを犯す可能性は少し低くなります。要素がドキュメントに含まれるか、含まれないかのどちらかです。

  • より複雑なシナリオ(ツリー化されたメニューの作成など)では、おそらくDOMコードを使用することになります。
  • より異種のコンテンツを含むドキュメントを作成するために複数のタイプのコンテンツを一緒に追加する必要があるシナリオでは、それはスラムダンクになります。親の追加コードを呼び出す前に、子の追加コードを呼び出す必要はありません。
  • 既存の静的コンテンツを追加、削除、または変更するシナリオでは、通常、DOMが優先されます。

複雑なDOM変更(最後に述べたものの1つ)を開始する場合は、jQueryなどのDOM変更を中心に構築されたライブラリを確認することをお勧めします。

于 2011-12-11T05:39:21.177 に答える