Poznajemy najważniejsze metody klasy Node. Kontynuacja lekcji poprzednich o JavaScript. Do dzieła.
Ok, najpierw insertBefore, które bywa mylące:
<ul id="languages">
<li>JavaScript</li>
<li>PHP</li>
</ul>
<script defer>
let ul = document.querySelector("#languages");
let textNode = document.createTextNode("Languages: ");
ul.insertBefore(textNode, null);
</script>
Ten kod doda nam napis „Languages: ” na końcu listy. Null musi być przekazany, bez nulla będzie błąd. Logika jest taka, że wywołujemy metodę na elemencie, przekazujemy node, które ma być dodane oraz element, przed którym ma być dodane.
Jeżeli chcemy ten napis na początku, musimy użyć:
let ul = document.querySelector("#languages");
let textNode = document.createTextNode("Languages: ");
ul.insertBefore(textNode, ul.firstChild);
Albo jeszcze lepiej:
let ul = document.querySelector("#languages");
let textNode = document.createTextNode("Languages: ");
ul.insertBefore(textNode, ul.firstElementChild);
A gdzie nam wyląduje textNode po takim kodzie:
let ul = document.querySelector("#languages");
let textNode = document.createTextNode("Languages: ");
ul.insertBefore(textNode, ul.lastChild);
Odpowiadam – po li PHP, przed ostatnim dzieckiem, jakim jest textNode „\n”. Nie tego się spodziewaliśmy, ale funkcja działa jak należy, to my nie umiemy przekazywać dobrze argumentów:
let ul = document.querySelector("#languages");
let textNode = document.createTextNode("Backend Languages: ");
ul.insertBefore(textNode, ul.lastElementChild);
Teraz mamy ten napis przed ostatnim li, czyli przed ostatnim dzieckiem-elementem.
Pokrętna logika tej funkcji, ale jedziemy dalej. Metoda n.appendChild:
<ul id="languages">
<li>JavaScript</li>
<li>PHP</li>
</ul>
<script defer>
let ul = document.querySelector("#languages");
let ts = document.createElement("li");
ts.appendChild(document.createTextNode("TypeScript"));
ul.insertBefore(ts, ul.lastElementChild);
</script>
Teraz mamy TypeScript przed PHP. Jako dziecko zostało dodane textNode do elementu li. Można je było ustawić przez textContent, zgoda, zatem kolejny przykład:
let ul = document.querySelector("#languages");
let ts = document.createElement("li");
ts.appendChild(document.createTextNode("TypeScript"));
ul.insertBefore(ts, ul.lastElementChild);
let csharp = document.createElement("li");
csharp.textContent = "C#";
ul.appendChild(csharp);
Teraz mamy C# na końcu, zaś TypeScript przed PHP.
Ok, teraz removeChild:
<ul id="languages">
Languages:
<li>JavaScript</li>
<li>TypeScript</li>
<li>PHP</li>
<li>C#</li>
</ul>
<script defer>
let ul = document.querySelector("#languages");
ul.removeChild(ul.firstElementChild);
</script>
Ten kod nam „zjada” li JavaScript. A jak usunąć textNode?
let ul = document.querySelector("#languages");
ul.removeChild(ul.firstChild);
Kolejna fajna metoda, hasChildNodes:
const list = document.getElementById("myList");
while (list.hasChildNodes()) {
list.removeChild(list.firstChild);
}
Ok, to z replaceChild będziemy mieli małe zadanie. Oto markup:
<ul id="languages">
Languages:
<li>JavaScript</li>
<li>TypeScript</li>
<li>PHP</li>
<li>C#</li>
</ul>
Mamy zamienić Languages na Backend Languages, zaś przed PHP wstawić Frontned Languages. Zwykły textNode, nie bawimy się w zagnieżdżone ul, choć tak to powinno wyglądać.
Mamy użyć replaceChild oraz insertBefore. Damy radę?
Oto przykład:
let ul = document.querySelector("#languages");
ul.replaceChild(
document.createTextNode("Frontned languages: "),
ul.firstChild
);
ul.insertBefore(
document.createElement("li").
appendChild(document.createTextNode("Backend Languages: ")),
ul.children[2]
);
Mam nadzieję, że wszystko rozumiemy, w tym:
- różnicę między firstChild a firstElementChild
- różnicę między childNodes a children
- różnicę między elementem a text node
To teraz jeszcze zwróćmy uwagę na chainowanie appendChild:
const fragment = document.createDocumentFragment();
const li = fragment
.appendChild(document.createElement("section"))
.appendChild(document.createElement("ul"))
.appendChild(document.createElement("li"));
li.textContent = "hello world";
document.body.appendChild(fragment);
Co ten kod nam da? Mam nadzieję, że nasza odpowiedź wygląda tak:
<section>
<ul>
<li>hello world</li>
</ul>
</section>