Warum ist das length-Attribut hier null?
Code:
function addListeners() {
var fields = document.getElementsByClassName("solutionField");
console.log(fields);
console.log(fields.length);
for (var i = 0; i < fields.length; i++) {
fields[i].addEventListener("transitionend", toggleBorder);
console.log("added");
}
}
Die Console-Logs:
Die Collection hat zwei Items, also warum ist length = 0 wenn ich versuche es auszulesen, obwohl es hier eigentlich 2 sein sollte?
3 Antworten
Wann wird der Code ausgeführt? Evtl. ist die Seite zu dem Zeitpunkt nicht geladen
Dann wird das ausgeführt bevor es vollst. geladen hat. Ne "unsaubere" Lösung ists den script tag kurz bevor du body schließt einzufügen
Ich finde Scripte im body schrecklich. Meiner Meinung nach gehören die in den head. Schließlich ist das der Bereich, wo man sowas definiert. Deshalb kann ich das defer attribute empfehlen. Dann funktioniert es auch im head
Google sagt etwas anderes;
"For scripts that are critical to the page contents and should be loaded first such as analytics, API, or authentication-type of scripts, it is recommended to place them in the head section of the HTML page. And other script tags should be placed at the bottom of the page before the closing </body> tag. "
...oder man lässt eine "Main"-Funktion per:
<body onload="myFunction()">
...aufrufen. Das onload -Event wird getriggert, wenn die Seite vollständig geladen ist. Damit wäre absolut sichergestellt, dass , egal wo irgendwas "verstreut" ist , auch bereits vorhanden ist.
Keine Frage, "irgendwo verstreut" ist kein guter Programierstil , aber ich habe schon "Pferde vor der Apotheke...🤮" . Besonders wenn copy&paste das Zepter schwangen.
...und natürlich gibt's auch Situationen, wo Aktionen laufen sollen, bevor eine Aktion ausgeführt wird: https://www.w3schools.com/tags/ref_eventattributes.asp .
...Das lässt sich nicht immer über die Position des Script-Tag im HTML steuern.🤔
Auch C# usw. haben ähnliche Events, welche (normalerweise) nicht explizit behandelt werden.
Im Falle von Html/JavaScript ist es nunmal so herum, dass DOM und (JavaScript) programm zwei verschiedene "Schuhe" sind und das Script nur mit dem arbeiten kann, was bereits vorhanden ist.
...aber auch in anderen Sprachen baust Du das GUI auf, bevor Du am Ende die Main-Funktion aufrufst... Nur das der Ablauf da nicht so augenfällig ist, weil der Compiler die Reihenfolge optimiert.
(auch bei WPF/Maui/Qt/... wird die GUIdefinition abgearbeitet, bevor der Programmcode ( main() ) ausgeführt wird.)
Naja, Google kann....
Er hat schon irgendwie Recht, es gibt ne Menge Zeug, das ausgeführt werden könnte/sollte, bevor man mit dem Laden der Seite fertig ist. Allerdings wäre es aus meiner Sicht Schwachsinn mit mehreren Scripttags zu arbeiten... und defer ist auch kein Allheilmittel.
Es gibt da mehrere Probleme die auftreten können. Deswegen habe ich eine eigene Variante für dich gebastelt:
function addListeners() {
document.addEventListener("DOMContentLoaded", ()=>{
let fields = document.querySelector(".solutionField");
console.log(fields);
console.log(fields.length);
fields.forEach(element => {
element.addEventListener("transitionend", toggleBorder);
});
console.log("added");
});
}
Es können Probleme auftreten wenn das DOM nicht geladen wurde bzw. nicht die gesuchten Elemente.
Eventuell ein Fehler in der Ausgabe Zeile.
Ich habe in der HTML-Datei das Script-Tag im Head.
Edit:
Ok...das war das Problem, wenn ich das Script-Tag am ende hintue funktioniert es