Node#

Node.insertBefore()#

Metoda insertBefore() dodaje przekazany węzeł przed wskazywane dziecko w danym węźle i zwraca referencję do dodawanego węzła.

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 other = node.insertBefore(other, child);

gdzie poszczególne człony oznaczają:

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

  1. Zwróć wynik przed wstawienia other do obiektu kontekstu przed child.

Do wywołania metody insertBefore() w powyższym zapisie składniowym potrzeba trzech odwołań: do rodzica, do nowego węzła oraz do dziecka. Składnię można nieco uprościć ograniczając się wyłącznie do dziecka i nowego węzła:

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
var other = child.parentNode.insertBefore(other, child);

Nie sprawdzi się to w sytuacji, kiedy przekazanym dzieckiem będzie wartość null, ale jest to dopuszczalne, i w tym osobliwym przypadku pozwala zasymulować działanie metody Node.appendChild().

Żadna specyfikacja nie definiuje bezpośrednio metody insertAfter(), ale możemy ją zaimplementować poprzez metodę insertBefore():

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
var other = parent.insertBefore(other, child.nextSibling);

Kiedy rodzic nie posiada żadnych dzieci lub wskazywane dziecko będące drugim argumentem jest ostatnim jego dzieckiem, to polecenie child.nextSibling zwróci wartość null, a to spowoduje, że dodawany węzeł będący pierwszym argumentem dołączony zostanie do rodzica i stanowić będzie jego jedyne lub ostatnie dziecko. Tym oto sposobem po raz kolejny otrzymujemy zachowanie identyczne z metodą Node.appendChild().

Analizując dokładnie wszystkie powiązane z metodą insertBefore() algorytmy można zauważyć, że przekazany węzeł będący pierwszym argumentem nie może istnieć jednocześnie w kilku miejscach drzewa węzłów. Najpierw zostanie usunięty z drzewa węzłów, a następnie wstawiony w nowe miejsce drzewa węzłów (z ewentualnym skorygowaniem jego właściciela). Jeśli zależy nam na wstawieniu drugiego identycznego węzła należy go najpierw sklonować i dopiero dołączyć do konkretnego drzewa węzłów. Trzeba pamiętać, że kopia nigdy nie będzie zsynchronizowana z oryginałem (są to dwa osobne obiekty), każda zmiana oryginału nie będzie miała żadnego wpływu na wykonaną kopię.

Warto podkreślić, że węzeł docelowy, na którym wywołujemy metodę insertBefore(), koniecznie musi być rodzicem dla przekazanego węzła stanowiącego drugi argument, ale nie może być jego dalszym przodkiem, w przeciwieństwie do metody Node.appendChild(), która pozbawiona jest takich ograniczeń.

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>

		// Uruchom po całkowitym załadowaniu dokumentu
		window.onload = function(){

			var ul1 = document.getElementById("ul1");
			var ul2 = document.getElementById("ul2");
			var newNode = ul1.getElementsByTagName("li")[0]; // referencja do pierwszego nowego węzła
			var beforeNode = ul2.getElementsByTagName("li")[0]; // referencja do węzła poprzedzającego

			// Manipulujemy drzewem po upływie 3 s
			setTimeout(function(){

				var ref = beforeNode.parentNode.insertBefore(newNode, beforeNode); // referencja do nowego węzła po jego dodaniu, to samo co newNode

				var nextNode = document.createElement("li"); // kolejny nowy węzeł
				nextNode.textContent = ref; // wartością tekstową uzyskaną po automatycznej konwersji ref będzie [object HTMLLIElement]

				ul2.insertBefore(nextNode, null); // identyczne działanie jak appendChild()

			}, 3000);

		}

	</script>

</head>

<body>
	<p>Lista 1</p>
	<ul id="ul1">
		<li><a href="">Pierwszy odsyłacz</a></li>
		<li><a href="">Drugi odsyłacz</a></li>
	</ul>

	<p>Lista 2</p>
	<ul id="ul2">
		<li><a href="">Drugi odsyłacz</a></li>
	</ul>
</body>

</html>

Składnia Web IDL#

  1. L
  2. K
  3. T'
  4. T
  5. A
  6. O
  7. Z'
  8. Z
  9. #
interface Node : EventTarget {
	Node insertBefore(Node other, Node? child);
}

Specyfikacje i inne materiały#

Pasek społecznościowy

SPIS TREŚCI AKTUALNEJ STRONY

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