HTMLCollection、NodeLists、およびオブジェクトの配列の違い


93

DOMに関しては、HTMLCollections、オブジェクト、配列の間で常に混乱していました。例えば...

  1. 違いは何ですか document.getElementsByTagName("td")とは$("td")
  2. $("#myTable")そして、$("td")オブジェクト(jQueryのオブジェクト)です。console.logにも横にDOM要素の配列が表示されるのはなぜですか。また、それらはオブジェクトではなく配列ではありませんか。
  3. とらえどころのない "NodeLists"とは何ですか、どのように選択するのですか?

以下のスクリプトの解釈も提供してください。

ありがとうございました

[123,"abc",321,"cba"]=[123,"abc",321,"cba"]
{123:123,abc:"abc",321:321,cba:"cba"}=Object { 123=123, abc="abc", 321=321, more...}
Node= Node { ELEMENT_NODE=1, ATTRIBUTE_NODE=2, TEXT_NODE=3, more...}
document.links= HTMLCollection[a #, a #]
document.getElementById("myTable")= <table id="myTable">
document.getElementsByClassName("myRow")= HTMLCollection[tr.myRow, tr.myRow]
document.getElementsByTagName("td")= HTMLCollection[td, td, td, td]
$("#myTable")= Object[table#myTable]
$("td")= Object[td, td, td, td]


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /> 
        <title>Collections?</title>  
        <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> 
        <script type="text/javascript">
            $(function(){
                console.log('[123,"abc",321,"cba"]=',[123,"abc",321,"cba"]);
                console.log('{123:123,abc:"abc",321:321,cba:"cba"}=',{123:123,abc:"abc",321:321,cba:"cba"});
                console.log('Node=',Node);
                console.log('document.links=',document.links);
                console.log('document.getElementById("myTable")=',document.getElementById("myTable"));
                console.log('document.getElementsByClassName("myRow")=',document.getElementsByClassName("myRow"))
                console.log('document.getElementsByTagName("td")=',document.getElementsByTagName("td"));
                console.log('$("#myTable")=',$("#myTable"));
                console.log('$("td")=',$("td"));
            });
        </script>
    </head>

    <body>
        <a href="#">Link1</a>
        <a href="#">Link2</a>
        <table id="myTable">
            <tr class="myRow"><td>td11</td><td>td12</td></tr>
            <tr class="myRow"><td>td21</td><td>td22</td></tr>
        </table>
    </body> 
</html>

後世のために以下を追加すると思います。()現代のJavaScriptでは、より良い比較がの間だろうdocument.querySelectorAll('td')$('td')。(b)基本的な違いは、jQueryが、とりわけHTML要素の番号付きコレクションを含む独自のタイプのオブジェクトで機能することです。このコレクションは上記のものではなく、jQueryオブジェクトは基本的に、真のDOM要素のラッパーです。
Manngo 2017年

回答:


112

まず、違いを説明します NodeListとをHTMLCollection

どちらのインターフェースもDOMノードのコレクションです。それらは、それらが提供するメソッドおよびそれらが含むことができるノードのタイプが異なります。にNodeListは任意のノードタイプを含めることができますが、にHTMLCollectionはElementノードのみを含めることが想定されています。
HTMLCollection同じメソッドを提供し、NodeListさらにと呼ばれるメソッドを提供しますnamedItem

コレクションは、複数のノードにアクセスを提供する必要がある場合に常に使用されます。たとえば、ほとんどのセレクターメソッド( getElementsByTagName)は複数のノードを返すか、すべての子への参照を取得します(element.childNodes)。

詳細については、 DOM4仕様-コレクションをください

違いは何ですか document.getElementsByTagName("td")とは$("td")

getElementsByTagNameDOMインターフェースのメソッドです。タグ名を入力として受け入れ、HTMLCollectionDOM4仕様を参照)。

$("td")おそらくjQueryです。有効なCSS / jQueryセレクターを受け入れ、jQueryオブジェクトを返します。

標準のDOMコレクションとjQuery選択の最大の違いは、DOMコレクションは通常ライブであるということです(ただし、すべてのメソッドがライブコレクションを返すわけではありません)。つまり、DOMへの変更は影響を受ける場合、コレクションに反映されます。これらはDOMツリーのビューのようなものですが、jQueryの選択は、関数が呼び出された瞬間のDOMツリーのスナップショットです。

console.logにも横にDOM要素の配列が表示されるのはなぜですか。また、オブジェクトや配列ではないのですか?

jQueryオブジェクトは配列のようなオブジェクトです。つまり、数値プロパティとプロパティを持っていますlength(配列は単なるオブジェクトそのものであることに注意してください)。ブラウザは、配列や配列のようなオブジェクトを次のような特別な方法で表示する傾向があります[ ... , ... , ... ]

とらえどころのない "NodeLists"とは何ですか、どのように選択するのですか?

私の答えの最初の部分を見てください。は選択 できませんNodeList。それらは結果です。です。

私が知る限り、NodeListプログラムでs を作成する方法(つまり、空のsを作成し、後でノードを追加する)さえない場合、それらは一部のDOMメソッド/プロパティによってのみ返されます。


2
@ user1032531:ええと、選択したDOM要素の1つに変更を加えた場合(たとえば、子の追加など)、もちろん同じDOM要素であるため、変更が表示されます。ただし、すべてのtd要素を選択した場合、td後で新しい要素を追加しても、新しい要素が含まれるように選択が自動的に更新されることはありません。
Felix Kling 2013

2
@FelixKling:すべてNodeListがライブであるわけではないことを述べておく必要があります。
Bergi

2
すべてがアレイだったらいいのに
SuperUberDuper 2015年

7
また、メソッド「keys」、「entries」、および「forEach」はNodeListに存在しますが、HTMLCollectionにはありません
Krzysztof Grzybek

2
@KrzysztofGrzybekそうです、それはとても迷惑です。なぜそれらの一体は一体.forEach()で、もう一方はそうではないのですか?
Robo Robok

29

0. an HTMLCollectionとaの違いは何NodeListですか?

ここにいくつかの定義があります。

DOMレベル1仕様-その他のオブジェクト定義

インターフェースHTMLCollection

HTMLCollectionはノードのリストです。個々のノードには、序数インデックスまたはノードの名前またはID属性のいずれかでアクセスできます。注:HTML DOMのコレクションはライブであると想定されます。つまり、基になるドキュメントが変更されると、コレクションは自動的に更新されます。

DOMレベル3仕様-NodeList

インターフェースNodeList

NodeListインターフェースは、このコレクションの実装方法を定義または制約せずに、ノードの順序付けられたコレクションの抽象化を提供します。DOMのNodeListオブジェクトはライブです。

NodeListの項目には、0から始まる整数インデックスを介してアクセスできます。

したがって、両方にライブデータを含めることができます。つまり、値が更新されるとDOMが更新されます。また、異なる機能セットも含まれています。

tableDOM要素にa childNodes NodeList[2]とaの両方が含まれていることをスクリプトを実行した場合にコンソールを検査するかどうかを確認しますchildren HTMLCollection[1]。なぜ違うのですか?HTMLCollection要素ノードのみを含めることができるため、NodeListにはテキストノードも含まれます。

ここに画像の説明を入力してください

1.の違いは何であるdocument.getElementsByTagName("td")とは$("td")

document.getElementsByTagName("td")DOM要素の配列(a NodeList)を返し$("td")ます。これはjQueryオブジェクトと呼ばれ、document.getElementsByTagName("td")そのプロパティ012、などの要素があります。主な違いは、jQueryオブジェクトの取得が少し遅いですが、すべての便利な機能にアクセスできます。 jQuery関数。

2. $("#myTable")および$("td")オブジェクト(jQueryオブジェクト)です。なぜですかconsole.logそれらの横にDOM要素の配列も表示されているのですか?それらはオブジェクトではなく、配列ではありませんか?

彼らは、プロパティを持つオブジェクトである012、などのDOM要素にセット。以下に簡単な例を示します。

jsFiddle

    var a = {
        1: "first",
        2: "second"
    }
    alert(a[1]);

3.とらえどころのない "NodeLists"とは何ですか。どのように選択するのですか?

あなたはあなたのコードでそれらを取得し、されているgetElementsByClassNamegetElementsByTagNameの両方のリターンNodeList

NodeList


3番目の応答でDOMをどのように表示しましたか?ありがとう!
user1032531 2013

@ user1032531はChrome開発ツールです。ちなみに答えの始めを更新しました。
Daniel Imms 2013

配列のようなログは、ほとんどがlengthプロパティの結果であり、数値のプロパティ名の結果ではありません。そして、文字列を警告するあなたの例は何と関係がありますconsole.logか?
Bergi

これは、オブジェクトに数値プロパティを設定する方法を示していました。私はそれらが配列ではなくオブジェクトであることを強調しようとしています。
Daniel Imms 2013

9

追記

HTMLCollectionとNodeListの違いは何ですか?

A HTMLCollectionは、要素ノードのみ(含まれているタグ)とのNodeListはすべて含まれているノードを

4つのノードタイプがあります。

  1. 要素ノード
  2. 属性ノード
  3. テキストノード
  4. コメントノード

nodeTypes

要素内の空白はテキストと見なされ、テキストはノードと見なされます。

以下を検討してください。

<ul id="myList">
  <!-- List items -->
  <li>List item 1</li> 
  <li>List item 2</li>
  <li>List item 3</li>
  <li>List item 4</li>
  <li>List item 5</li>
</ul>

空白: <ul id="myList"> <li>List item</li></ul>

空白なし: <ul id="myList"><li>List item</li></ul>

HTMLCollectionとNodeListの違い


2

$("td")拡張jQueryオブジェクトであり、jQueryメソッドがあり、htmlオブジェクトの配列を含むjqueryオブジェクトを返します。document.getElementsByTagName("td")未加工のjsメソッドで、NodeListを返します。この記事を見る


Karaxunaに感謝します。はい、その記事を見ました。それが役に立ったかどうかは分かりませんが、間違いなく私にもっと質問をさせてくれました:)
user1032531

@karaxunaに感謝します。非常によく説明された有用な記事。
ジュゼッペ

0

NodeListオブジェクトはxで、たとえば返されたノードのコレクションの、あります。childNodesプロパティまたはdocument.querySelectorAll()メソッド。場合によっては、NodeListはliveです。つまり、DOMの変更により、コレクションが自動的に更新されます。たとえば、Node.childNodesはライブです。

var c = parent.childNodes; //assume c.length is 2
parent.appendChild(document.createElement('div'));
//now c.length is 3, despite the `c` variable is assigned before appendChild()!!
//so, do not cache the list's length in a loop.

しかし、他のいくつかのケースでは、NodeListはstaticであり、DOMの変更はコレクションのコンテンツに影響しません。querySelectorAll()は静的なNodeListを返します。

HTMLCollectionはありライブや注文した要素のコレクション(基本となる文書が変更されたときに、それが自動的に更新されます)。それは、などのような性質の結果であることが可能で、子供などの方法document.getElementsByTagName() 、および可能性だけ持っているのHTMLElementの彼らのアイテムとして。

HTMLCollectionは、名前とインデックスの両方によって、そのメンバーをプロパティとして直接公開します。

var f = document.forms; // this is an HTMLCollection
f[0] === f.item(0) === f.myForm //assume first form id is 'myForm'

HTMLElementはノードの1つのタイプにすぎません。

ノード<< HTMLElement継承

ノードにはいくつかのタイプがあります。最も重要なものは次のとおりです。

  • element(1):<p>or などのElementノード<div>
  • 属性(2):要素の属性。要素の属性は、DOM4仕様のNodeインターフェースを実装しなくなりました!
  • text(3):要素または属性の実際のテキスト。
  • コメント(8):コメントノード。
  • document(9):ドキュメントノード。

したがって、大きな違いは、HTMLCollectionにはHTMLElementsのみが含まれるが、NodeListにはコメント、空白テキスト(キャリッジリターン文字、スペースなど)も含まれることです。次のスニペットのように確認してください。

function printList(x, title) {
  console.log("\r\nprinting "+title+" (length="+x.length+"):");
  for(var i=0; i<x.length; i++) {
    console.log("  "+i+":"+x[i]);
  }
}

var elems = document.body.children; //HTMLCollection
var nodes = document.body.childNodes; //NodeList

printList(elems, "children [HTMLCollection]");
printList(nodes, "childNodes [NodeList]");
<div>para 1</div><!-- MyComment -->
<div>para 2</div>

HTMLCollectionとNodeListの両方に、項目をループするために使用できる長さプロパティが含まれています。for ... inまたはfor ...... inを使用してNodeListの項目を列挙しないでください。長さと項目のプロパティも列挙され、スクリプトが要素オブジェクトのみを処理する必要があると想定している場合はエラーが発生するためです。また、for..inが特定の順序でプロパティを訪問することは保証されていません。

for (var i = 0; i < myNodeList.length; i++) {
  var item = myNodeList[i];
}

0

あまりにも多く、すでに言われますが、間の違いを説明するための例とその答えの多くの要約版を考えてきたHTMLCollectionし、NodeList役立つだろう。

DOMのノードのタイプ

  • 12の異なるノードタイプがあり、さまざまなノードタイプの子を持つことができます。

ここに画像の説明を入力してください

  • 次の3つのプロパティを使用して、DOMのノードを検査および照会できます。

    • nodeType 物件
    • nodeName 物件
    • nodeValue 物件
  • nodeTypeプロパティは、指定されたノードの数として、ノードのタイプを返します。

    • ノードが要素ノードの場合、nodeTypeプロパティは1を返します。
    • ノードが属性ノードの場合、nodeTypeプロパティは2を返します。
    • ノードがテキストノードの場合、nodeTypeプロパティは3を返します。
    • ノードがコメントノードの場合、nodeTypeプロパティは8を返します。
    • このプロパティは読み取り専用です。

HTMLCollectionとNodeList

ここに画像の説明を入力してください

次の例では、HTMLCollectionとの違いをNodeListより明確に理解できます。理解を深めるために、独自のブラウザコンソールで出力を確認してください。

<ul>
  <li>foo</li>
  <li>bar</li>
  <li>bar</li>
</ul>
// retrieve element using querySelectorAll
const listItems_querySelector = document.querySelectorAll('li');
console.log('querySelector', listItems_querySelector);

// retrieve element using childNodes
const list  = document.querySelector('ul')
const listItems_childNodes = list.childNodes;
console.log('childNodes', listItems_childNodes);
const listItems_children = list.children;
console.log('children', listItems_children);

const listItems_getElementsByTagName = document.getElementsByTagName('li');
console.log('getElementsByTagName', listItems_getElementsByTagName);

console.log('*************************');
console.log('add one list item');
console.log('*************************');
list.appendChild(document.createElement('li'));

console.log('querySelector', listItems_querySelector);
console.log('childNodes', listItems_childNodes);
console.log('children', listItems_children);
console.log('getElementsByTagName', listItems_getElementsByTagName);

console.log('*************************');
console.log('add one more list item');
console.log('*************************');
listItems_getElementsByTagName[0].parentNode.appendChild(document.createElement('li'));

console.log('querySelector', listItems_querySelector);
console.log('childNodes', listItems_childNodes);
console.log('children', listItems_children);
console.log('getElementsByTagName', listItems_getElementsByTagName); 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.