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:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
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ą:

Algorytm wywołania metody namedItem(key) nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:

  1. Jeśli key jest pustym łańcuchem znakowym, to zwróć wartość null.
  2. Zwróć pierwszy węzeł elementowy zawarty w obiekcie kontekstu, dla którego jeden z poniższych warunków będzie prawdziwy:

    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:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<!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:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
<!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#

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
[LegacyUnenumerableNamedProperties]
interface HTMLCollection {
	getter Element? namedItem(DOMString name);
}

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

HTMLCollection (H1) HTMLCollection.namedItem() (H2) Opis działania (H3) Składnia Web IDL (H3) Specyfikacje i inne materiały (H3)