Perbedaan antara HTMLCollection, NodeLists, dan array objek

94

Saya selalu bingung antara HTMLCollections, objek, dan array ketika datang ke DOM. Contohnya...

  1. Apa perbedaan antara document.getElementsByTagName("td")dan $("td")?
  2. $("#myTable")dan $("td")objek (objek jQuery). Mengapa console.log juga menampilkan larik elemen DOM di sampingnya, dan bukankah itu objek dan bukan larik?
  3. Apa itu "NodeLists" yang sulit dipahami, dan bagaimana cara memilihnya?

Berikan juga interpretasi apa pun dari skrip di bawah ini.

Terima kasih

[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>
pengguna1032531
sumber
Saya pikir saya bisa menambahkan yang berikut untuk anak cucu. (a) Dalam JavaScript modern, perbandingan yang lebih baik adalah antara document.querySelectorAll('td')dan $('td'). (b) Perbedaan mendasar adalah bahwa jQuery bekerja dengan jenis objeknya sendiri yang berisi, antara lain, kumpulan elemen HTML bernomor ; koleksi ini bukan salah satu yang di atas, dan objek jQuery pada dasarnya adalah pembungkus di sekitar elemen DOM yang sebenarnya.
Manngo

Jawaban:

113

Pertama saya akan menjelaskan perbedaan antara NodeListdan HTMLCollection.

Kedua antarmuka adalah kumpulan node DOM. Mereka berbeda dalam metode yang mereka sediakan dan dalam jenis node yang dapat dikandungnya. Meskipun NodeListdapat berisi jenis node apa pun, an HTMLCollectionseharusnya hanya berisi node Elemen.
An HTMLCollectionmenyediakan metode yang sama dengan a NodeListdan sebagai tambahan metode yang dipanggil namedItem.

Koleksi selalu digunakan saat akses harus disediakan ke banyak node, misalnya sebagian besar metode pemilih (seperti getElementsByTagName) mengembalikan beberapa node atau mendapatkan referensi ke semua anak ( element.childNodes).

Untuk informasi lebih lanjut, lihat spesifikasi DOM4 - Koleksi .

Apa perbedaan antara document.getElementsByTagName("td")dan $("td")?

getElementsByTagNameadalah metode antarmuka DOM. Ia menerima nama tag sebagai masukan dan mengembalikan HTMLCollection(lihat spesifikasi DOM4 ).

$("td")mungkin adalah jQuery. Ini menerima pemilih CSS / jQuery yang valid dan mengembalikan objek jQuery.

Perbedaan terbesar antara koleksi DOM standar dan pilihan jQuery adalah bahwa koleksi DOM biasanya hidup (meskipun tidak semua metode mengembalikan koleksi langsung), yaitu setiap perubahan pada DOM tercermin dalam koleksi jika terpengaruh. Mereka seperti tampilan pada pohon DOM, sedangkan pilihan jQuery adalah snapshot dari pohon DOM pada saat fungsinya dipanggil.

Mengapa console.log juga menampilkan larik elemen DOM di sampingnya, dan bukankah itu objek dan bukan larik?

Objek jQuery adalah objek seperti array , yaitu mereka memiliki properti numerik dan lengthproperti (perlu diingat bahwa array hanyalah objek itu sendiri). Browser cenderung menampilkan array dan objek seperti array dengan cara khusus, seperti [ ... , ... , ... ].

Apa itu "NodeLists" yang sulit dipahami, dan bagaimana cara memilihnya?

Lihat bagian pertama dari jawaban saya. Anda tidak dapat memilih NodeList s, ini adalah hasil dari pemilihan.

Sejauh yang saya tahu bahkan tidak ada cara untuk membuat secara NodeListterprogram (yaitu membuat yang kosong dan menambahkan node di kemudian hari), mereka hanya dikembalikan oleh beberapa metode / properti DOM.

Felix Kling
sumber
2
@ user1032531: Nah, jika Anda membuat perubahan ke salah satu elemen DOM yang dipilih (misalnya menambahkan anak), maka Anda tentu saja akan melihat perubahan karena itu satu dan elemen DOM yang sama. Namun, dengan asumsi Anda memilih semua tdelemen, menambahkan tdelemen baru nanti tidak akan memperbarui pilihan secara otomatis untuk memuat elemen baru.
Felix Kling
2
@FelixKling: Anda harus menyebutkan bahwa tidak semua NodeLists yang hidup.
Bergi
2
Saya berharap mereka semua adalah array
SuperUberDuper
7
Tampaknya juga bahwa metode "kunci", "entri" dan "forEach" saya ada di NodeList, tetapi hilang di HTMLCollection
Krzysztof Grzybek
2
@KrzzzGrzybek Benar dan itu sangat menyebalkan. Mengapa salah satu dari mereka memiliki .forEach()dan yang lainnya tidak?
Robo Robok
30

0. Apa perbedaan antara an HTMLCollectiondan a NodeList?

Berikut beberapa definisi untuk Anda.

Spesifikasi DOM Level 1 - Definisi Objek Lain-lain :

Antarmuka HTMLCollection

HTMLCollection adalah daftar node. Sebuah node individu dapat diakses baik oleh indeks ordinal atau nama node atau atribut id. Catatan: Koleksi di DOM HTML diasumsikan hidup yang berarti bahwa mereka secara otomatis diperbarui ketika dokumen yang mendasarinya diubah.

Spesifikasi DOM Level 3 - NodeList

Antarmuka NodeList

Antarmuka NodeList menyediakan abstraksi dari kumpulan node yang diurutkan, tanpa menentukan atau membatasi bagaimana kumpulan ini diimplementasikan. Objek NodeList di DOM sedang live.

Item di NodeList dapat diakses melalui indeks integral, mulai dari 0.

Jadi keduanya bisa berisi data langsung yang berarti DOM akan diperbarui saat nilainya. Mereka juga berisi sekumpulan fungsi yang berbeda.

Anda akan mencatat jika Anda memeriksa konsol jika Anda menjalankan skrip Anda bahwa tableelemen DOM berisi a childNodes NodeList[2]dan a children HTMLCollection[1]. Mengapa mereka berbeda? Karena HTMLCollectionhanya dapat berisi node elemen, NodeList juga berisi node teks.

masukkan deskripsi gambar di sini

1. Apa perbedaan antara document.getElementsByTagName("td")dan $("td")?

document.getElementsByTagName("td")kembali array elemen DOM (a NodeList), $("td")disebut objek jQuery yang memiliki unsur-unsur dari document.getElementsByTagName("td")pada sifat-sifatnya 0, 1, 2, dll Perbedaan utama adalah bahwa objek jQuery sedikit lebih lambat untuk mengambil tetapi memberikan akses ke semua berguna fungsi jQuery.

2. $("#myTable")dan $("td")merupakan objek ( jQueryobjek). Mengapa console.logjuga menampilkan larik elemen DOM di sampingnya, dan bukankah itu objek dan bukan larik?

Mereka adalah obyek dengan sifat mereka 0, 1, 2, dll set untuk elemen DOM. Berikut adalah contoh sederhana: cara kerjanya:

jsFiddle

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

3. Apa yang dimaksud dengan "NodeLists" yang sulit dipahami, dan bagaimana cara memilihnya?

Anda telah mengambilnya dalam kode Anda, getElementsByClassNamedan getElementsByTagNamekeduanya mengembalikan NodeLists

NodeList

Daniel Imms
sumber
Bagaimana Anda menampilkan DOM dalam tanggapan ketiga Anda? Terima kasih!
pengguna1032531
@ user1032531 itu adalah alat pengembang Chrome. Ngomong-ngomong, saya memperbarui awal jawaban.
Daniel Imms
Log mirip larik sebagian besar merupakan hasil dari lengthproperti, bukan dari nama properti numerik. Dan apa hubungan contoh Anda dalam memberi tahu string console.log?
Bergi
Itu menunjukkan bagaimana Anda bisa memiliki properti numerik pada objek. Saya mencoba untuk menekankan fakta bahwa mereka adalah objek, bukan array.
Daniel Imms
9

Catatan tambahan

Apa perbedaan antara HTMLCollection dan NodeList?

Sebuah HTMLCollection hanya berisi node elemen ( tag ) dan NodeList berisi semua node .

Ada empat jenis node:

  1. simpul elemen
  2. simpul atribut
  3. simpul teks
  4. simpul komentar

nodeTypes

Spasi kosong di dalam elemen dianggap sebagai teks, dan teks dianggap sebagai node.

Pertimbangkan hal berikut:

<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>

Spasi Putih: <ul id="myList"> <li>List item</li></ul>

Tanpa spasi: <ul id="myList"><li>List item</li></ul>

Perbedaan antara HTMLCollection dan NodeList

Matahari
sumber
2

$("td")adalah objek jQuery yang diperluas dan memiliki metode jQuery, ia mengembalikan objek jquery yang berisi larik objek html. document.getElementsByTagName("td")adalah metode js mentah dan mengembalikan NodeList. Lihat artikel ini

karaxuna
sumber
Terima kasih Karaxuna. Ya, saya telah melihat artikel itu. Tidak tahu apakah itu membantu, tapi pasti membuat saya mengajukan lebih banyak pertanyaan :)
user1032531
Terima kasih @karaxuna. Artikel yang berguna, dijelaskan dengan sangat baik.
Giuseppe
0

The NodeList objek adalah koleksi Node ini, kembali misalnya dengan x. properti childNodes atau metode document.querySelectorAll () . Dalam beberapa kasus, NodeList adalah hidup , yang berarti bahwa perubahan dalam DOM secara otomatis memperbarui koleksi! Misalnya, Node.childNodes adalah live:

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.

Namun dalam beberapa kasus lain, NodeList bersifat statis , di mana setiap perubahan di DOM tidak memengaruhi konten koleksi. querySelectorAll () mengembalikan NodeList statis.

The HTMLCollection adalah hidup dan memerintahkan kumpulan elemen (secara otomatis diperbarui ketika dokumen yang mendasari berubah). Ini bisa jadi hasil dari properti seperti sebagai anak atau metode seperti sebagai document.getElementsByTagName () , dan hanya dapat memiliki HTMLElement sebagai itemnya.

HTMLCollection juga mengekspos anggotanya secara langsung sebagai properti dengan nama dan indeks:

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

HTMLElement hanyalah salah satu jenis Node:

Node << warisan HTMLElement

Node dapat terdiri dari beberapa jenis . Yang terpenting adalah sebagai berikut:

  • elemen (1): Sebuah simpul Elemen seperti <p>atau <div>.
  • atribut (2): Atribut dari sebuah Elemen. Atribut elemen tidak lagi mengimplementasikan antarmuka Node dalam spesifikasi DOM4!
  • teks (3): Teks sebenarnya dari Elemen atau Atribut.
  • comment (8): Sebuah node komentar.
  • document (9): Sebuah node dokumen.

Jadi, perbedaan besar adalah bahwa HTMLCollection hanya berisi HTMLElements tetapi NodeList juga berisi komentar, teks spasi putih (karakter karakter balik, spasi ..), dll. Periksa seperti pada cuplikan berikut:

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>

Baik HTMLCollection dan NodeList berisi properti panjang yang dapat Anda gunakan untuk mengulang item mereka. Jangan gunakan untuk ... di atau untuk setiap ... in untuk menghitung item di NodeLists, karena mereka juga akan menghitung panjang dan properti item dan menyebabkan kesalahan jika skrip Anda menganggapnya hanya harus berurusan dengan objek elemen. Selain itu, for..in tidak dijamin untuk mengunjungi properti dalam urutan tertentu.

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

Begitu banyak yang telah diceritakan, tetapi pikirkan versi jawaban yang lebih ringkas dengan contoh untuk menjelaskan perbedaan antara HTMLCollectiondan NodeListakan membantu.

Jenis Node di DOM

  • Ada 12 jenis node berbeda, yang mungkin memiliki turunan dari berbagai jenis node:

masukkan deskripsi gambar di sini

  • Kita dapat menggunakan tiga properti berikut untuk memeriksa dan menanyakan tentang node di DOM:

    • nodeType Properti
    • nodeName Properti
    • nodeValue Properti
  • The nodeTypeproperti mengembalikan jenis node, sebagai angka, dari node tertentu.

    • Jika node adalah node elemen, nodeTypeproperti akan mengembalikan 1 .
    • Jika node adalah node atribut, nodeTypeproperti akan mengembalikan 2 .
    • Jika node adalah node teks, nodeTypeproperti akan mengembalikan 3 .
    • Jika node adalah node komentar, nodeTypeproperti akan mengembalikan 8 .
    • Properti ini hanya-baca.

HTMLCollection vs NodeList

masukkan deskripsi gambar di sini

Kita dapat memahami perbedaan antara HTMLCollectiondan NodeListlebih jelas dengan contoh berikut. Silakan, coba periksa keluarannya di konsol browser Anda sendiri untuk mendapatkan pemahaman yang lebih baik.

<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); 
Shraddha
sumber