Gunnar Bittersmann: Anzahl von Kind-Elementen zählen

Beitrag lesen

@@claus ginsel

versteh ich dein JS richtig, dass der Eventhandler erst im Ereignisfall auf das auslösende Element gesetzt und zugleich ausgeführt wird?

Ich glaube nicht.

const itemlist = document.querySelector('table');
itemlist.addEventListener('click', (event) => {
  // …
});

ist ja im Wesentlichen das, was du auch hattest. Mit ein paar Unterschieden:

  • Ich nenne das Ding nicht table, sondern itemlist. Ist ja keine richtige Datentabelle. Ich war auch schon geneigt, <table role="presentation"> zu setzen, wodurch Screenreader das nicht als Tabelle ansagen.

  • Ich hab der Tabelle keine ID gegeben; ist ja in meinem Beispiel nicht nötig, weil die einzige. Bei dir ist das völlig richtig, das Ding über dessen ID anzusprechen (wobei "tab" kein sinnvoller Bezeichner ist). Ich würde das allerdings nicht mit getElementById() tun und auch nicht das von @Friedel ins Spiel gebrachte getElementsByTagName() verwenden, sondern querySelector() bzw. querySelectorAll() – ein einheitliches API für alle Fälle.

  • Nicht onclick, sondern addEventListener().

  • Die Eventhandlerfunktion bekommt event als Parameter. Wir werden gleich sehen, warum.

Es werden nicht Eventhandler für jedes einzelne interaktive Element registriert, sondern ein Eventhandler für deren gemeinsames Vorfahrenelement, wo alle click-Events durch Bubbling eintreffen. Also event delegation.

Ich habe in meinem Beispiel (Link öffnet auch die Konsole) noch hinzugefügt:

	console.log(event.target.nodeName);

event.target liefert das Element, das der Nutzer geclickt hat. Beim Click auf den Button steht bei Tastaturbedienung "BUTTON" in der Konsole; bei Mausbedienung hingegen "SPAN", weil ja auf das span-Element mit dem 🗑-Icon geclickt wird. Beim Mausclick außerhalb des Buttons wird "TD" ausgegeben.

(Die Codezeile ist nur zur Veranschauung und hat im Produktiv-Code nichts zu suchen.)

Als nächstes wird abgefragt, ob der bei itemlist ankommende click-Event von innerhalb eines Buttons kommt (d.h. vom button selbst (Tastaturbedienung) oder einem darin befindlichen Nachfahrenelement (Mausbedienung)):

	if (event.target.closest('button')) {

Die Aktion Löschen soll nur ausgeführt werden, wenn ein Löschen-Button betätigt wurde. Wenn man woanders hinclickt, soll nichts passieren.

(Das hattest du anders? Halte ich für einen Designfehler. Insbesondere, weil bei dir noch der ⤓ hinzukommt; und verschachtelte Clickflächen sind nicht die beste Idee.)

Wenn ein Löschen-Button betätigt wurde, wird dessen übergeordnetes tr-Element ermittelt (es soll ja genau dieses gelöscht werden, nicht irgendein anderes):

		const item = event.target.closest('tr');

Bei dir passiert da natürlich noch was anderes. – Und bei jedem Item dasselbe, d.h. die letzte Abfrage in meinem Beispiel

		if (!item.querySelector('#unsere-liebe')) {

wirst du nicht haben. Die ist nur deshalb, weil unsere Liebe nicht bricht.

🖖 Живіть довго і процвітайте

--
„Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
— @Grantscheam auf Twitter