NodeListはいつ生きていて、いつ静止しているのか?
質問
に対する MDN から ノードリスト :
場合によっては、NodeList はライブコレクションであり、DOM の変更がコレクションに反映されることを意味します。 DOM の変更がコレクションに反映されることを意味します。例えば Node.childNodes はライブです。
var parent = document.getElementById('parent'); var child_nodes = parent.childNodes; console.log(child_nodes.length); // let's assume "2" parent.appendChild(document.createElement('div')); console.log(child_nodes.length); // should output "3"
他のケースでは NodeList は静的なコレクションであり、その後の DOM の変更がコレクションの内容に影響しないことを意味します。 DOM が変更されても、コレクションの内容には影響しません。 document.querySelectorAllは静的なNodeListを返します。
だから......ちょっと迷惑!?DOM API のさまざまな部分をすべて個別にチェックすることなく、どのメソッドがライブのリストを返し、どのメソッドがスタティックなリストを返すかについての中央リファレンスはあるのでしょうか? また ルール があるのでしょうか?
どのように解決するのですか?
各メソッドの情報には、ライブかどうかの詳細が書かれていますが、それを判断するための標準的な規約はないようです。
document.getElementsByClassName()
は
HTMLCollection
であり、ライブである。
document.getElementsByTagName()
は
HTMLCollection
であり、ライブである。
document.getElementsByName()
は
NodeList
であり、ライブである。
document.querySelectorAll()
は
NodeList
であり
ではない
を生きている。
HTMLCollection
は常にライブであるように見える
HTMLCollectionはノードのリストである。個々のノードは 序数か、ノードのnameかid属性でアクセスできます。
注意: HTML DOM のコレクションはライブであると仮定されます。 つまり、基礎となるドキュメントが変更されると、自動的に更新されます。 という意味です。
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506
つまり、HTMLコレクションは
常に
であり、一方
nodeList
はより一般的な構成で、DOM にあるかどうかわかりません。
NodeList オブジェクトはノードのコレクションです... NodeList インターフェースは、ノードの順序付きコレクションの抽象化を提供します。 ノードのコレクションを抽象化したもので、このコレクションがどのように実装されるかを定義したり制限したりすることはありません。 を定義または制限することなく、ノードの順序付きコレクションの抽象化を提供します。DOM の NodeList オブジェクトは生きています。
http://www.w3.org/TR/DOM-Level-3-Core/core.html#td-live
いい感じでしょう?
<ブロッククオートコレクションは、DOMノードのリストを表すオブジェクトです。A コレクションはライブでもスタティックでも構いません。特に断りのない限り、コレクションは コレクションはライブでなければなりません。
http://www.w3.org/TR/2012/WD-dom-20120405/#collections
というわけで、静的コレクションは仕様でそのように示されることになります。つまり、このロジックで
document.querySelectorAll()
はコレクションですが、それは
ではなく
になっています。なぜなら、コレクションはライブであってもなくても良いのですが、コレクションは
で
は生きていなければならないからです...。この区別は超便利ではありません。
さて、ここで、ある文字列が
collection
が生きているかどうかを判定する簡単な方法です。
DOM
に追加し (セレクタにマッチするように)、長さが変更されたかどうかを確認し、削除します (したがってページには影響がありません)。
デモ
function isLive(collection) {
if (HTMLCollection.prototype.isPrototypeOf(collection)) return true // HTMLCollections are always live
const length = collection.length;
if (!length) return undefined; // Inconclusive
const el = collection.item(0);
const parent = el.parentNode;
const clone = el.cloneNode();
clone.style.setProperty('display', 'none', 'important');
parent.appendChild(clone);
const live = collection.length !== length;
parent.removeChild(clone);
return live;
}
const divs1 = document.getElementsByClassName('c');
const divs2 = document.getElementsByTagName('span');
const divs3 = document.getElementsByName('notFound');
const divs4 = document.querySelectorAll('.c');
console.log("document.getElementsByClassName('c'):", divs1.toString()); // [object HTMLCollection]
console.log("document.getElementsByTagName('notFound'):", divs2.toString()); // [object HTMLCollection]
console.log("document.getElementsByName('notFound'):", divs3.toString()); // [object NodeList]
console.log("document.querySelectorAll('.c'):", divs4.toString()); // [object NodeList]
console.log('isLive(divs1)', isLive(divs1)); // true
console.log('isLive(divs2)', isLive(divs2)); // true
console.log('isLive(divs3)', isLive(divs3)); // undefined
console.log('isLive(divs4)', isLive(divs4)); // false
<html>
<body>
<div>
<div class="c">C1</div>
<div class="c">C2</div>
</div>
<div>
<div class="c">C3</div>
<div class="c">C4</div>
</div>
</body>
</html>
関連
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] CSSでcellpaddingとcellspacingを設定する?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] URLを新しいタブで開く(新しいウィンドウではない)
-
[解決済み] 画面サイズ、現在のウェブページ、ブラウザウィンドウのサイズを取得する
-
[解決済み] Node.jsを使うタイミングをどう判断するか?
-
[解決済み] JSのDateからDay名
-
[解決済み] JavaScriptでjson-objectのキーを取得する [重複].
-
[解決済み] jQueryを使用して、すべてのクリックイベントハンドラを削除するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Google maps API V3 - 同一地点に複数のマーカーを設置する。
-
[解決済み] ExtJS 4のイベントハンドリングについて
-
[解決済み] アサインの左側にJavascriptのオブジェクトブラケット表記({ ナビゲーション } =)があります。
-
[解決済み] 文字列がhtmlであるかどうかをチェックする
-
[解決済み] Javascript / jQueryでAndroid端末を検出する。
-
[解決済み] jQueryの$という記号の意味は何ですか?
-
[解決済み] javascript includes() 大文字小文字を区別しない
-
[解決済み] moment.jsでミュータビリティを回避するには?
-
[解決済み] BlobからArrayBufferへ移行する方法
-
[解決済み] TypeScriptプロジェクトで既存のC#クラス定義を再利用する方法