ChildNode#
ChildNode.replaceWith()#
Metoda replaceWith()
zastępuje przekazanymi węzłami i/lub łańcuchami znakowymi dany węzeł w jego rodzicu.
Opis działania#
Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:
childNode.replaceWith(nodes);
gdzie poszczególne człony oznaczają:
- childNode - węzeł będący obiektem kontekstu.
- nodes - referencja do przekazanych węzłów i/lub łańcuchów znakowych (automatycznie zamienianych na węzły tekstowe) zastępujących dany węzeł. Separatorem między wieloma przekazanymi argumentami jest przecinek.
Algorytm wywołania metody replaceWith(nodes)
nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:
- Niech parent będzie rodzicem w obiekcie kontekstu.
- Jeśli parent jest wartością
null
, to pomiń kolejne kroki. - Niech viableNextSibling będzie pierwszym następnikiem bratowym dla obiektu kontekstu, który nie znajduje się w nodes, w przeciwnym razie niech będzie wartością
null
. - Niech node będzie wynikiem skonwertowania nodes do węzła.
- Jeśli rodzicem w obiekcie kontekstu jest parent, to zastąp dany obiekt kontekstu przez node w rodzicu posiadanym przez obiekt kontekstu.
W przeciwnym razie wykonaj przed wstawienie node do parent przed viableNextSibling.
Krok wynika z tego, że obiekt kontekstu mógł zostać przekazany w nodes, dlatego też po skonwertowaniu we wcześniejszym kroku znalazł się w node.
Warto podkreślić, że węzeł docelowy, na którym wywołujemy metodę replaceWith()
, nie musi mieć rodzica, i w takiej sytuacji nie wykonane zostaną żadne czynności (bez zgłoszenia jakiegokolwiek błędu). Co ciekawe, jeśli nie przekażemy żadnego argumentu do metody to uzyskamy zbliżone zachowanie jak w metodzie ChildNode.remove()
.
Analizując dokładnie wszystkie powiązane z metodą replaceWith()
algorytmy można zauważyć, że przekazane węzły nie mogą istnieć jednocześnie w kilku miejscach drzewa węzłów. Najpierw zostaną usunięte z drzewa węzłów, a następnie wstawione w nowe miejsce drzewa węzłów (z ewentualnym skorygowaniem ich właściciela). Jeśli zależy nam na wstawieniu kolejnych identycznych węzłów należy je 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ę.
Metoda replaceWith()
, w przeciwieństwie do metody Node.replaceChild()
, nie zwraca referencji do zastępowanego węzła, ale nie jest to szczególnie istotne, gdyż samo jej wywołanie wymaga uprzedniego dostępu do zastępowanego węzła.
Prosty przykład:
<!DOCTYPE html>
<html>
<head>
<script>
// Uruchom po całkowitym załadowaniu dokumentu
window.onload = function(){
var ul1 = document.getElementById("ul1");
var whatNode = ul1.getElementsByTagName("li")[1]; // referencja do węzła zastępującego
var replaceNode = document.getElementById("ul2").getElementsByTagName("li")[0];
// Manipulujemy drzewem po upływie 3 s
setTimeout(function(){
replaceNode.replaceWith(whatNode);
}, 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="">Pierwszy odsyłacz</a></li>
</ul>
</body>
</html>
Na chwilę obecną jedynie przeglądarka Firefox zaimplementowała metodę replaceWith()
.
Metoda replaceWith()
pojawia się dopiero w specyfikacji DOM4.
Składnia Web IDL#
[NoInterfaceObject] interface ChildNode { [Unscopable] void replaceWith((Node or DOMString)... nodes); }