メインコンテンツへ移動

JS 学習ノート 5_DOM

無料2015-04-09#JS#dom

この記事では様々な DOM ノード、DOM 操作およびパフォーマンス最適化戦略について紹介します

##1.DOM ノードの常用属性(すべてのノードがサポート)##

  1. nodeType:要素 1、属性 2、テキスト 3

  2. nodeName:要素タグ名の大文字形式

  3. nodeValue:要素ノードは null、テキストノードはテキスト内容、属性ノードは属性値

  4. 関係属性:parentNode、childNodes、nextSibling、previousSibling、firstChild、lastChild

  5. ownerDocument:ドキュメントノード(document オブジェクト)

##2.DOM ノードの操作(追加/削除/変更)##

  1. appendChild(node); 現在のノードの childNodes リストの末尾にノードを追加します。node が既に存在する場合、node を現在のノードの下に移動します

  2. insertBefore(node, targetNode); targetNode の前に node を挿入します

  3. replaceChild(node, targetNode); node で targetNode を置き換えます。注意:置き換え後、targetNodeは破棄されません。DOM ツリーの外に浮かぶドキュメントフラグメントになっただけです

  4. removeChild(node); node を削除します。注意:削除後、nodeも破棄されません。このメソッドは node の参照を返します

  5. cloneNode(true/false); 現在のノードと完全に同じノードをコピーします。true なら深層コピー、そうでなければ浅層コピー。IE は関連イベントハンドラをコピーします。他のブラウザはコピーしません

  6. normalize(); 空のテキストノードを削除し、隣接するテキストノードをマージするために使用します

##3.document オブジェクト関連##

  1. document.documentElement; 要���を指します

  2. document.body; 要素を指します

  3. document.title; 要素を指し、直接代入してドキュメントタイトルを変更できます

  4. document.URL; 完全な URL を取得します

document.domain; ドメイン名を取得します。ドメイン名を直接代入して設定できます。ページ内の複数の frame が通信する必要がある場合、この属性を変更してクロスドメインセキュリティ制限を解除する必要があります

document.referrer; 前のページの url を取得します。空文字列の可能性があります

  1. 要素の検索

    • document.getElementById(str);

    • document.getElementsByTagName(str); コレクションを返します。角括構文でアクセスします。角括内は name 属性値で要素を取得する文字列です(str は*で、すべての DOM 要素を取得できます)

    • document.getElementsByName(str); 主にラジオボタングループに使用されます

P.S. 最初の 2 つはすべての XML ドキュメントの DOM 操作に適用され、最後は HTML ドキュメントのみに適用されます。HTML5 でサポートされている document.querySelector(str) および document.getElementsByClassName(str) についてはここでは議論しません。上記の 3 つの方法はすべて全ブラウザ対応です

  1. document.write(str); ドキュメント書き込み。ドキュメント読み込み中に直接呼び出すと指定位置に内容を出力します。load イベントハンドラ内に配置するとページ全体を書き換えます

  2. document.createTextNode(text); テキストノードを作成します。document.createElement(tagName); 要素を作成します

##4.要素ノード関連##

  1. 要素ノードの属性:id、title(ToolTip に類似)、className。すべて読み取り/書き込み可能です(ネイティブ js コードを書く際、これら 3 つの属性は非常によく使用され、特にclassNameが便利です)

  2. elem.getAttribute(attr); attr 属性の値を取得します。カスタム属性も取得できますが、HTML5 ではカスタム属性に"data-"プレフィックスを付ける必要があります(もちろん、付けなくても問題ありませんが、仕様规范要求)。elem.dataset.attr で取得します

elem.setAttribute(attr, value); 属性値を設定します。カスタム属性の設定にのみ使用します。カスタム属性は直接設定できないためです

elem.removeAttribute(attr); 属性と値を削除します([IE6-] はサポートしていません

P.S. 通常は属性に直接アクセスします。例えば elem.id、elem.style など。get/setAttribute 方式はあまり使用されません(カスタム属性の読み取り/書き込みのみ)。関数方式で style や onclick やその他のイベント属性にアクセスすると文字列が返されるためです。直接アクセスすると操作可能なオブジェクト(関数参照など)が返されるため、通常は要素属性に直接アクセスします

  1. attributes 属性:elem.attributes['id'].nodeValue = value; この方法で属性にアクセスすることもできますが、より多くの場合、attributes 属性を使用して要素属性を遍历します

  2. 要素ノードを遍历する際は nodeType 検出を追加する必要があります。一部のブラウザはタグ間の空白文字もノードとして扱うためです(Unicode 署名 BOM

##5.テキストノード##

node.nodeValue または node.data でテキスト内容にアクセスできます

##6.DOM パフォーマンス最適化##

  1. NodeList へのアクセス回数を最小限に抑える

NodeList、NamedNodeMap、HTMLCollection はすべてリアルタイム更新されます。document.getElementByxxx の戻り値はこのタイプです。NodeList へのアクセス回数を最小限に抑える必要があります。アクセス時に DOM ツリーをチェックする必要があるため、かなりのパフォーマンス損失があるためです。NodeList オブジェクトの参照を保存しておくべきです。例えば、以下のコードは避けてください:

    for(var i = 0;i < 100;i++){
      document.getElementsByTagName('li')[i].className = 'disabled';
    }

これは非常に良くありません。より良い方法は:

    var lis = document.getElementsByTagName('li');
    for(var i = 0;i < 100;i++){
      lis[i].className = 'disabled';
    }

一般的な HTMLCollection オブジェクト:document.forms、document.images、document.links、document.anchors

  1. DocumentFragment を使用して複数回の「現場更新」を回避

DocumentFragment は比較的マイナーですが非常に有用なノードです。パフォーマンス最適化において特に重要です。大量の DOM ノードを挿入する必要がある場合、2 つの選択肢があります:1 つずつ DOM ツリーに挿入するか、まずドキュメントフラグメントに挿入してから、ドキュメントフラグメントを DOM ツリーに挿入するかです。最初の方式は DOM ツリーを n 回更新する必要がありますが、2 番目の方式は 1 回だけ更新すれば済みます。例えば:

    //创建文档碎片
    var frag = document.createDocumentFragment();
    //插入节点
    var node = null, text = null;
    for(var i = 0;i < 10;i++){
      node = document.createElement('p');
      text = document.createTextNode('段落' + i);
      node.appendChild(text);
      frag.appendChild(node);
    }
    //把携带着节点的文档碎片插入 DOM 树
    document.body.appendChild(frag);

ドキュメントフラグメントは DOM ツリーには存在しません。フラグメントを DOM ツリーに挿入することは、実際にはそれが持つノードを挿入することです。ドキュメントフラグメントは見えないコンテナです。もちろん、コンテナとして div を作成することもできます。ドキュメントフラグメントを作成するのと同じ道理です。n 回の現場更新を回避できれば良いのです。DOM ツリーのどのノードが更新されてもブラウザはページを再レンダリングするため、大量のスタイル数値計算が必要になるからです

  1. getElementByxxx のパフォーマンス差異

Id 検索が最も速く、TagName がその次、ClassName が最も遅いです。もちろん、通常これらの差異は無視できますが、モバイル端ページでは十分に考慮すべきです。モバイル端には PC のような良い条件がないためです。さらに、頻繁に使用する要素の参照を保存しておくと、不要な DOM 検索を減らし、パフォーマンスを向上させることができます。

##7.動的に img/script/link 要素を作成##

この部分は一般的な DOM 操作とは異なり、イベントとの関連が多いため、JS 学習ノート 6_イベント で詳しく説明します

コメント

コメントはまだありません

コメントを書く