HTMLCollection, NodeLists ve nesne dizileri arasındaki fark


94

Konu DOM olduğunda HTMLCollections, nesneler ve diziler arasında her zaman kafam karıştı. Örneğin...

  1. Arasındaki fark nedir document.getElementsByTagName("td")ve $("td")?
  2. $("#myTable")ve $("td")nesnelerdir (jQuery nesneleri). Console.log neden yanlarında DOM öğeleri dizisini de gösteriyor ve bunlar nesne değil ve dizi değil mi?
  3. Zor "Düğüm Listeleri" ne hakkında ve birini nasıl seçerim?

Lütfen aşağıdaki komut dosyasının herhangi bir yorumunu da sağlayın.

teşekkür ederim

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

Sanırım gelecek nesil için aşağıdakileri ekleyebilirim. (a) Modern JavaScript'te, document.querySelectorAll('td')ve arasında daha iyi bir karşılaştırma olacaktır $('td'). (b) Temel fark, jQuery'nin, diğer şeylerin yanı sıra numaralandırılmış bir HTML öğeleri koleksiyonu içeren kendi nesne türü ile çalışmasıdır ; bu koleksiyon yukarıdakilerin hiçbiri değildir ve jQuery nesnesi esasen gerçek DOM öğelerinin etrafındaki bir sarmalayıcıdır .
Manngo

Yanıtlar:


113

İlk önce NodeListve arasındaki farkı açıklayacağım HTMLCollection.

Her iki arayüz de DOM düğümlerinin koleksiyonlarıdır . Sağladıkları yöntemlerde ve içerebilecekleri düğüm türlerinde farklılık gösterirler. A NodeListherhangi bir düğüm türünü HTMLCollectioniçerebilirken, anın yalnızca Element düğümlerini içermesi beklenir.
An HTMLCollection, a ile aynı yöntemleri sağlar NodeListve ek olarak namedItem.

Koleksiyonlar, erişimin birden çok düğüme sağlanması gerektiğinde her zaman kullanılır, örneğin çoğu seçici yöntem (örneğin getElementsByTagName) birden çok düğümü döndürür veya tüm alt öğelere bir referans alma ( element.childNodes).

Daha fazla bilgi için, DOM4 spesifikasyonu - Koleksiyonlara bakın .

Arasındaki fark nedir document.getElementsByTagName("td")ve $("td")?

getElementsByTagNameDOM arayüzünün yöntemidir. Bir etiket adını girdi olarak kabul eder ve bir döndürür HTMLCollection(bkz. DOM4 özelliği ).

$("td")muhtemelen jQuery'dir. Herhangi bir geçerli CSS / jQuery seçiciyi kabul eder ve bir jQuery nesnesi döndürür.

Standart DOM koleksiyonları ile jQuery seçimleri arasındaki en büyük fark, DOM koleksiyonlarının tipik olarak canlı olmasıdır (tüm yöntemler canlı bir koleksiyon döndürmez), yani, DOM'daki herhangi bir değişiklik etkilenirse koleksiyonlara yansıtılır. DOM ağacındaki bir görünüm gibidirler , oysa jQuery seçimleri, işlevin çağrıldığı andaki DOM ağacının anlık görüntüleridir.

Console.log neden yanlarında DOM öğeleri dizisini de gösteriyor ve bunlar nesne değil ve dizi değil mi?

jQuery nesneleri dizi benzeri nesnelerdir, yani sayısal özelliklere ve bir lengthözelliğe sahiptirler (dizilerin yalnızca nesneler olduğunu unutmayın). Tarayıcılar dizileri ve dizi benzeri nesneleri özel bir şekilde görüntüleme eğilimindedir [ ... , ... , ... ].

Zor "Düğüm Listeleri" ne hakkında ve birini nasıl seçerim?

Cevabımın ilk kısmına bakın. Sen olamaz seçmek NodeList s, bunlar sonuç bir seçim.

NodeListProgramatik olarak s yaratmanın bir yolu bile olmadığını bildiğim kadarıyla (yani boş bir tane oluşturmak ve daha sonra düğüm eklemek), bunlar yalnızca bazı DOM yöntemleri / özellikleri tarafından döndürülür.


2
@ user1032531: Seçili DOM öğelerinden birinde herhangi bir değişiklik yaparsanız (örneğin, bir çocuk eklemek), o zaman elbette tek ve aynı DOM öğesi olduğu için değişikliği göreceksiniz. Ancak, tüm tdöğeleri seçtiğinizi varsayarsak , tddaha sonra yeni bir öğe eklemek, yeni öğeyi içerecek şekilde seçimi otomatik olarak güncellemeyecektir.
Felix Kling

2
@FelixKling: Bunu tüm bahsetmeliyiz NodeListler canlı bulunmaktadır.
Bergi

2
Keşke hepsi dizi olsaydı
SuperUberDuper

7
Ayrıca NodeList'te bulunan, ancak HTMLCollection'da eksik olan "anahtarlar", "girişler" ve "forEach" yöntemleri
Krzysztof Grzybek

2
@KrzysztofGrzybek Bu doğru ve çok sinir bozucu. Neden biri var .forEach(), diğeri yok?
Robo Robok

30

0. an HTMLCollectionve a arasındaki fark nedir NodeList?

İşte sizin için bazı tanımlar.

DOM Seviye 1 Spesifikasyonu - Çeşitli Nesne Tanımları :

Arayüz HTMLCollection

HTMLCollection, düğümlerin bir listesidir. Tek bir düğüme, sıralı dizin veya düğümün adı veya kimlik öznitelikleri ile erişilebilir. Not: HTML DOM'daki koleksiyonların canlı olduğu varsayılır, yani temeldeki belge değiştirildiğinde otomatik olarak güncellenirler.

DOM Düzey 3 Spesifikasyonu - Düğüm Listesi

Arabirim Düğüm Listesi

NodeList arabirimi, bu koleksiyonun nasıl uygulandığını tanımlamadan veya kısıtlamadan sıralı bir düğüm koleksiyonunun soyutlamasını sağlar. DOM'daki NodeList nesneleri canlıdır.

NodeList'teki öğelere, 0'dan başlayarak bir integral indeks aracılığıyla erişilebilir.

Böylece her ikisi de canlı veriler içerebilir, bu da DOM'nin değerleri değiştiğinde güncelleneceği anlamına gelir. Ayrıca farklı işlevler de içerirler.

Eğer bu senin komut dosyalarını çalıştırmak eğer konsol incelemek eğer dikkat edecek tableDOM öğesi a hem de içerir childNodes NodeList[2]ve bir children HTMLCollection[1]. Neden farklılar? Çünkü HTMLCollectionsadece eleman düğümleri içerebilir, NodeList da bir metin düğümü içerir.

görüntü açıklamasını buraya girin

1. document.getElementsByTagName("td")ve arasındaki fark nedir $("td")?

document.getElementsByTagName("td")döner DOM elemanlı bir dizi, (a NodeList), $("td")elemanları olan bir jQuery nesne olarak adlandırılır document.getElementsByTagName("td"), özelliklerine 0, 1, 2vb temel fark jQuery amacı, biraz daha yavaş almak için, ancak tüm kullanışlı erişim sağlamasıdır jQuery işlevleri.

2. $("#myTable")ve $("td")nesnelerdir ( jQuerynesneler). Neden console.logyanlarında DOM öğeleri dizisi de gösteriliyor ve bunlar nesne değil, dizi değil mi?

Onlar kendi özellikleri ile nesnelerdir 0, 1, 2, DOM elemanlarına vb seti. İşte basit bir örnek: nasıl çalıştığına dair:

jsFiddle

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

3. Bulunması zor "Düğüm Listeleri" ne hakkında ve birini nasıl seçerim?

Kodunuzdaki bunları almak edilmiş, getElementsByClassNameve getElementsByTagNamede dönüp NodeLists

Düğüm Listesi


DOM'u 3. yanıtınızda nasıl görüntülediniz? Teşekkürler!
user1032531

@ user1032531 bu Chrome geliştirme araçlarıdır. Bu arada cevabın başlangıcını güncelledim.
Daniel IMMS

Dizi benzeri günlük, lengthsayısal özellik adlarının değil , çoğunlukla özelliğin bir sonucudur . Ve bir dizgeyi uyarma örneğinizin ne ile ilgisi var console.log?
Bergi

Bu, nesneler üzerinde nasıl sayısal özelliklere sahip olabileceğinizi gösteriyordu. Diziler değil, nesneler oldukları gerçeğini vurgulamaya çalışıyorum.
Daniel IMMS

9

Ek not

HTMLCollection ile NodeList arasındaki fark nedir?

Bir HTMLCollection yalnızca öğe düğümlerini ( etiketleri ) içerir ve bir NodeList tüm düğümleri içerir .

Dört düğüm türü vardır:

  1. eleman düğümü
  2. öznitelik düğümü
  3. metin düğümü
  4. yorum düğümü

nodeTypes

Öğelerin içindeki boşluk metin olarak kabul edilir ve metin düğümler olarak kabul edilir.

Aşağıdakileri göz önünde bulundur:

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

Beyaz boşluk: <ul id="myList"> <li>List item</li></ul>

Boşluk yok: <ul id="myList"><li>List item</li></ul>

HTMLCollection ve NodeList arasındaki fark


2

$("td")genişletilmiş jQuery nesnesidir ve jQuery yöntemlerine sahiptir, html nesnelerinin dizisini içeren jquery nesnesini döndürür. document.getElementsByTagName("td")ham js yöntemidir ve NodeList'i döndürür. Bu makaleye bakın


Teşekkürler Karaxuna. Evet, o makaleye baktım.
Yardımcı

Teşekkürler @karaxuna. Faydalı makale, çok iyi açıklanmış.
Giuseppe

0

NodeList nesneler x örneğin döndürülen Düğüm en koleksiyonları vardır. childNodes özelliği veya document.querySelectorAll () yöntemi. Bazı durumlarda, NodeList olan canlı DOM değişiklikler otomatik olarak güncelleştirmek o hangi araçları! Örneğin, Node.childNodes yayında:

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.

Ancak diğer bazı durumlarda, NodeList statiktir , burada DOM'daki herhangi bir değişiklik koleksiyonun içeriğini etkilemez. querySelectorAll () , statik bir NodeList döndürür.

HTMLCollection bir olan canlı ve sipariş elementlerin toplanması (otomatik yatan belge değiştiğinde güncellenir). Bu gibi özelliklerin sonucu olabilir çocuklar olarak benzeri veya yöntemlerin document.getElementsByTagName () ve tek olabilir HTMLElement var onların öğeleri olarak.

HTMLCollection ayrıca üyelerini hem ada hem de dizine göre doğrudan özellikler olarak gösterir:

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

HTMLElement yalnızca bir tür Düğümdür:

Düğüm << HTMLElement devralma

Düğüm birkaç tür olabilir . En önemlileri aşağıdaki gibidir:

  • eleman (1): <p>veya gibi bir Eleman düğümü <div>.
  • özellik (2): Bir Öğenin Özniteliği. Öğe özellikleri artık DOM4 belirtiminde Düğüm arayüzünü uygulamıyor!
  • text (3): Öğenin veya Özniteliğin gerçek Metni.
  • yorum (8): Bir yorum düğümü.
  • belge (9): Bir belge düğümü.

Bu nedenle, büyük bir fark, HTMLCollection'ın yalnızca HTMLElements içermesi, ancak NodeList'in ayrıca yorumları, beyaz boşluk metinlerini (satır başı karakterleri, boşluklar ...) vb. İçermesidir. Aşağıdaki kod parçacığında olduğu gibi kontrol edin:

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>

Hem HTMLCollection hem de NodeList , öğeleri üzerinde döngü yapmak için kullanabileceğiniz length özelliğini içerir . NodeLists içindeki öğeleri numaralandırmak için for ... in veya for each ... in kullanmayın, çünkü bunlar aynı zamanda uzunluk ve öğe özelliklerini de numaralandıracak ve betiğiniz yalnızca öğe nesneleriyle uğraşması gerektiğini varsayarsa hatalara neden olacaktır. Ayrıca, for..in'in mülkleri belirli bir sırada ziyaret etmesi garanti edilmez.

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

0

Zaten çok şey söylendi, ancak aradaki farkları açıklamak için bir örnekle yanıtın daha özetlenmiş bir versiyonunu düşündüm HTMLCollectionve NodeListyardımcı olacaktı.

DOM’daki Düğüm Türleri

  • Çeşitli düğüm türlerinin alt öğelerine sahip olabilen 12 farklı düğüm türü vardır:

görüntü açıklamasını buraya girin

  • DOM'daki düğümleri incelemek ve sorgulamak için aşağıdaki üç özelliği kullanabiliriz:

    • nodeType Emlak
    • nodeName Emlak
    • nodeValue Emlak
  • nodeTypeÖzelliği belirtilen düğümün, bir sayı olarak, düğüm türü döner.

    • Düğüm bir eleman düğümü ise, nodeTypeözellik 1 döndürür .
    • Düğüm bir öznitelik düğümü ise, nodeTypeözellik 2 döndürür .
    • Düğüm bir metin düğümü ise, nodeTypeözellik 3 döndürür .
    • Düğüm bir açıklama düğümü ise, nodeTypeözellik 8 döndürür .
    • Bu özellik salt okunurdur.

HTMLCollection ve NodeList karşılaştırması

görüntü açıklamasını buraya girin

Aşağıdaki örnekle arasındaki farkları HTMLCollectionve NodeListdaha net bir şekilde anlayabiliriz . Daha iyi anlamak için lütfen kendi tarayıcı konsolunuzdaki çıktıları kontrol etmeyi deneyin.

<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); 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.