closest() – nächstes übergeordnetes Element mit Selektor
closest() gibt das nahegelegenste übergeordnete Element – einen Vorfahren oder Container – zurück, das einem CSS-Selektor entspricht, oder eine Referenz auf sich selber, wenn das Element selbst schon zum Selektor passt. Das erspart viele Abfragen und macht den Scriptcode lesbarer.
closest – Suche den übergeordneten Container
Das ist genauso komfortabel wie die gleichnamige jQuery-Methode und wird von allen modernen Browsern unterstützt. Die Suche nach den Vorfahren oder umfassenden Elementen gehört vor allem in Slideshows und verschachtelten Menüs zu den wiederkehrenden Aufgaben.
elem.closest(selector)
closest() findet das nächste übergeordnete Element – einen Container oder Vorfahren – anhand eines einfachen Selektors. closest() gehört zu den eleganten jQuery-Methoden, die wir im reinen Javascript lange schmerzlich vermisst haben.
Inzwischen gehört closest() zu den DOM-Methoden von Vanilla Javascript, und wird auch schon auf den älteren Versionen der mobilen Geräte (iOS ab Version 9, Android 76 ) unterstützt.
const caption = document.querySelectorAll(".cards figcaption");
for (const elem of caption) {
elem.addEventListener ("click", (eve) => {
const figure = elem.closest("figure");
let card = figure.querySelector("lamp-desc");
card.classList.toggle ("visible");
elem.classList.toggle ("open")
})
}
Die herkömmlichen Methoden parentNode oder parentElement erwischten nur den direkten Vorfahren und mussten in einer Schleife bei jedem Vorfahren fragen, ob er dem gewünschten Selektor entspricht.
matches()
Passt gut zu closest: matches(). matches() stellt fest, ob ein Element zum einem bestimmten Selektor passt. matches wird von allen modernen Browsern unterstützt, nur IE11 brauchte noch einen Präfix.
if (elem.matches(selector))
Ein find() als Pendant zu closest() – so wie in jQuery – gibt es übrigens nicht, und obendrein ist find() schon von array besetzt.
parentElement
querySelectorAll, getElementsByTagName und getElementsByClassName geben NodeLists (auch Collections oder Sammlungen) zurück – das sind keine Arrays. Für die Bestimmung des Index in einer NodeList wird parentNode oder parentElement gebraucht:
- Ananas
- Erdbeere
- Melone
<ul class="fruity"> <li>Ananas</li> <li>Erdbeere</li> <li>Melone</li> </ul>
// Index in einer Nodelist mit parentNode oder parentElement finden
var images = ["fruity-01.svg","fruity-02.svg","fruity-03.svg",];
var fruity = document.querySelectorAll(".fruity li");
for (var i=0; i<fruity.length; i++) {
fruity[i].addEventListener ('click', function () {
var img = document.createElement("IMG");
var index = Array.prototype.indexOf.call(this.parentElement.children, this);
img.setAttribute("src",images[index]);
document.querySelector(".demonodes").appendChild(img);
});
}
Anstelle von parentElement hätte parentNode denselben Zweck erfüllt, denn es ist so gut wie ausgeschlossen, dass ein Text, ein Zeilenumbruch oder ein Kommentar ein parentNode ist.
Unterschied zwischen parentElement/parentNode und elem.closest(). elem.closest() steigt nach oben, bis es passt, während parentElement / parentNode eine Ebene nach oben gehen.
| Methode | Geht nach oben | Sucht nach Selector | Inkludiert sich selbst |
|---|---|---|---|
| parentNode | ja, nur direkter Parent | nein | nein |
| parentElement | ja, nur direkter Parent (HTMLElement) | nein | nein |
| closest() | ja, alle Ebenen nach oben | ja | ja |