0

createDocumentFragment()は以下のコードで何かをしていますか?

私はこのコードを適応させようとしています。それがどのように機能するのかわかりませんし、forループはを要求していないようですtableFrag。あなたの洞察?

function createTable(searchResults)
{
    var results_table = 
        document.getElementById("report_results").getElementsByTagName("table")[0];

    var newLink, tableFrag;
    tableFrag = document.createDocumentFragment();
    tableFrag.appendChild(results_table);

    for (result_index in searchResults.results)
    {
        newRow = results_table.getElementsByTagName("tbody")[0].insertRow(-1);

        newCell = newRow.insertCell(-1);
        newCell.appendChild(document.createTextNode(searchResults.results[result_index]["score"]));

        newCell = newRow.insertCell(-1);
        newLink = document.createElement("a");
        newLink.href = 
            "officer.php?officer_seq="+searchResults.results[result_index]["officer_seq"];
        newLink.appendChild(document.createTextNode(searchResults.results[result_index]["officer_id"]));
        newCell.appendChild(newLink);

        newRow = null;
    }
    document.getElementById("report_results").appendChild(tableFrag);
}

具体的には、私を不思議に思うのはtableFrag、ループに見つからないことです。

    for (result_index in searchResults.results)
    {
        ...
        tableFrag this-or-that
        ...
    }
    document.getElementById("report_results").appendChild(tableFrag);
4

3 に答える 3

1

フラグメントは、results_tableの元のdomを格納する方法として使用されているように見えます。次に、forループはresults_tableに変更を加えます。それが完了すると、フラグメント(元のテーブルを含む)がresults_tableの最後に追加されます。

基本的には、新しい検索結果をテーブルの一番上に配置し、古い結果を一番下に移動するため、フラグメントとforループの両方が何かを実行します。

于 2012-11-30T21:08:13.027 に答える
1

このコードのドキュメントフラグメントの目的は、DOMからテーブルを一時的に削除することです。

  1. テーブルをDOMからフラグメントに移動します
  2. テーブルに対して操作を実行します
  3. テーブルをフラグメントからDOMに戻します

このアプローチでは、フラグメントに対して2つのDOM操作のみを使用します(ステップ1および3)。これにより、ステップ2で必要となるすべてのリフローをスキップできます。

各DOM操作操作(たとえば、DOM内のテーブルに行を追加する)により、ページのリフローが発生します(Webブラウザーはページを再計算し、再描画します)。複数のDOM操作操作を順番に実行する場合(たとえば、複数の行を追加する場合)、各操作の後にリフローを行う必要はありません。プロセス全体の後でのみ、ページはリフローする必要があります。これを実現するには、テーブルをフラグメントに移動して、一時的にDOMから切り離す必要があります。DOMから外れている要素は、リフローを引き起こしません。

于 2012-11-30T21:29:32.597 に答える
1

はい、それは何かをしています:パフォーマンスの最適化。

HTMLドキュメントの要素は、DOMインターフェイス(またはなどのメソッド)を介してアクセスできるツリーデータ構造に保持されます。このツリーが操作されるたびに、つまり、Javascriptコードを介してノードを挿入、削除、または変更すると、ブラウザのレンダリングエンジンは、CSSで定義されたルールに応じてボックスをリレーアウトし(これはリフローとも呼ばれます、ブラウザのウィンドウにツリーの表示部分を再描画する必要があります。document.getElementById(id)document.getElementsByClassName()

あなたの場合、テーブルに固定数の行を追加する必要があります。ループが開始Nされると、テーブルに行を追加する必要があることがすでにわかっています。DOM要素に行を追加するだけの場合、ブラウザーを呼び出すたびtable.appendChild(row)にページの測定、レイアウト、ペイントが行われ、これはほとんどの場合に発生しNます(実際には、ブラウザーはこれらのコストのかかる操作を抑制しますが、これはどの仕様でも必須ではないため、学習目的で、追加するたびに、ブラウザがツリーを無効にして再描画すると想定できます)。

この処理はすべて不要です。ブラウザが一度に1行ずつテーブルを視覚的に拡大するのではなくN、1回のショットで、一種のトランザクションで行をテーブルに配置するだけです。DocumentFragmentこの正確な目的のために存在します。フラグメントの子を操作する場合、ブラウザは何も測定およびレイアウトしません。これは、最終的にフラグメントをメインDOMに追加した場合にのみ発生します。私たちの想像上の単純化されたブラウザでは、ペイントルーチンは時間ではなく1回だけ呼び出されますN

したがって、スクリプトが行うことは、フラグメントを作成し、メインDOMからテーブルを削除し、ノードをフラグメントに追加し、フラグメントにアタッチされている間にテーブルを操作し、最後にフラグメント全体をメインDOMに追加します(子が最終的に測定され、レイアウトされ、ペイントされました。コードは明示的にテーブルをDOMから削除しないことに注意してください。ただし、これはNode.appendChild(node)、子ノードがすでに何らかの階層に属している場合にメソッドが行うことです。

指定された親ノードの子のリストの最後にノードを追加します。ノードがすでに存在する場合は、現在の親ノードから削除されてから、新しい親ノードに追加されます。

MDNDocumentFragmentについて詳しく読むことができます。

于 2012-12-07T21:22:23.817 に答える