HTMLCollection#
HTMLCollection.namedItem()#
Metoda namedItem()
zwraca pierwszy węzeł elementowy o określonej wartości atrybuty id
lub name
z danej kolekcji elementowej. Jeśli w kolekcji elementowej nie ma elementu spełniającego te wymagania lub przekażemy pusty łańcuch znakowy to zwrócona zostanie wartość null
.
Opis działania#
Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:
var element = htmlCollection.namedItem(key); var element = htmlCollection[key]; // alternatywa z JS var element = htmlCollection.key; // alternatywa z JS
gdzie poszczególne człony oznaczają:
- element - referencja do zwracanego elementu lub wartość
null
. - htmlCollection - kolekcja elementowa będąca obiektem kontekstu.
- key - łańcuch znakowy reprezentujący wartość atrybutu
id
lubname
, którą posiada poszukiwany element w kolekcji elementowej.
Algorytm wywołania metody namedItem(key)
nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:
- Jeśli key jest pustym łańcuchem znakowym, to zwróć wartość
null
. Zwróć pierwszy węzeł elementowy zawarty w obiekcie kontekstu, dla którego jeden z poniższych warunków będzie prawdziwy:
- posiada unikatowy identyfikator, który jest wskazywany przez key.
- ma swój atrybut
name
, którego wartością jest key;
lub wartość
null
jeśli w obiekcie kontekstu nie ma takiego węzła elementowego.
W przypadku alternatywy z JS dla metody namedItem()
mamy do czynienia z pojęciem obsługiwanych nazw właściwości.
Wielkość znaków w wartości atrybuty id
i name
oraz w argumencie przekazanym do metody ma znaczenie zarówno w dokumentach XML jak i HTML. Wielkość znaków w nazwie lokalnej samego atrybutu jest nieistotna tylko w przypadku dokumentów HTML, czyli przykładowo nazwy "name"
lub "NAME"
wskazują na ten sam atrybut.
To właśnie ze względu na metodę namedItem()
pozostawiono interfejs HTMLCollection w DOM4, chociaż działanie metody zostało zmodyfikowane. Obecnie przeszukiwanie elementów kolekcji pod kątem określonej wartości (zarówno w atrybucie id
jak i name
) jest równoważne, chociaż w przeszłości pierwszeństwo miał id
. Ogólnie rzecz biorąc ważna jest jedynie zgodność argumentu przekazanego do metody z wartością któregokolwiek z tych atrybutów.
Wyjątkiem będzie oczywiście sytuacja, kiedy ten sam element będzie miał zarówno atrybut id
jak i name
. W takiej sytuacji, zgodnie z powyższym algorytmem, pierwszeństwo powinien mieć identyfikator (i jest to zgodne także z HTML5). W praktyce byłoby to istotne jedynie przy wyliczaniu indeksów nazwanych (np. za pomocą pętli for in
), ale od pewnego czasu DOM4 nie zezwala na wyliczanie tego typu indeksów w kolekcji elementowej (zgodnie z DOM - Bug 24624).
#W przeglądarkach zgodnych z najnowszymi specyfikacjami wszystkie indeksy nazwane w kolekcji elementowej, które są reprezentowane przez wartości w atrybutach id
oraz name
, powinny zostać pominięte przy wyliczaniu. W definicji Web IDL jest to sygnalizowane poprzez zastosowanie atrybutu rozszerzającego [LegacyUnenumerableNamedProperties]
. Wydaje się, że w tej kwestii najwłaściwiej zachowują się przeglądarki Firefox i Opera (Presto), gdyż faktycznie pomijają wszystkie niewyliczalne właściwości.
Prosty przykład:
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function(){
var collection = document.getElementsByTagName("div");
var info = document.getElementById("info");
for (var prop in collection) {
info.innerHTML += prop + "<br>"; // zwracamy wszystkie wyliczalne właściwości kolekcji
}
}
</script>
</head>
<body>
<div id="id1" name="name1"></div>
<div id="id2" name="name1"></div>
<div id="id3"></div>
<div id="id4" name="name4"></div>
<div name="name5"></div>
<p id="info"></p>
</body>
</html>
Kolejny prosty przykład:
<!DOCTYPE html>
<html>
<head>
<script>
function getItem(name){
var collection = document.getElementById("contener").children; // pobranie kolekcji z dowolnymi węzłami elementowymi
var child = collection.namedItem(name); // pobranie elementu węzłowego z określonym id lub name
var info = document.getElementById("info");
info.innerHTML = "Interfejs kolekcji: " + collection // [object HTMLCollection]
+ "<br>" + "Właściwość length: " + collection.length;
if (child){
info.innerHTML += "<br><br>" + "Interfejs dziecka: " + child
+ "<br>" + "Właściwość textContent: " + child.textContent;
}
else{
info.innerHTML += "<br><br>Wartość: " + String(child)
}
}
</script>
</head>
<body>
<div id="contener">
<p name="test">Pierwszy akapit (name="test") w kontenerze DIV.</p>
<p id="test">Drugi akapit (id="test") w kontenerze DIV.</p>
<p id="Test">Trzeci akapit (id="Test") w kontenerze DIV.</p>
<p name="Test">Czwarty akapit (name="Test") w kontenerze DIV.</p>
</div>
<p>Kliknij przycisk by pobrać konkretny element z kolekcji elementów kontenera DIV.</p>
<input type="button" value="div.children.namedItem('test')" onclick="getItem('test')">
<input type="button" value="div.children.namedItem('Test')" onclick="getItem('Test')">
<input type="button" value="div.children.namedItem('TEST')" onclick="getItem('TEST')">
<p style="color: blue;">Szczegółowe informacje dla pobranej kolekcji:</p>
<p id="info"></p>
</body>
</html>
Na chwilę obecną jedynie przeglądarka Firefox obsługuje metodę namedItem()
zgodnie z najnowszymi wymaganiami specyfikacji DOM4. W przypadku Opery (Presto) mamy do czynienia ze starym błędem, kiedy to metoda nie zwraca pojedynczego elementu, tylko nową kolekcję elementową z pasującymi elementami. W Chrome atrybut id
ma pierwszeństwo przed atrybutem name
. IE11 zwraca pojedynczy element, ale nie ma rozróżniania wielkości znaków w argumencie przekazanym do metody.
Składnia Web IDL#
[LegacyUnenumerableNamedProperties] interface HTMLCollection { getter Element? namedItem(DOMString name); }