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.