Fehlerquelle: JavaScript versucht auf noch nicht vorhandene Elemente zuzugreifen

Im letzten Kapitel haben wir gesehen, dass folgendes JavaScript-Programm mit der Fehlermeldung „Uncaught TypeError: Connot read property …“ abgebrochen ist.

<html>
<head>
	<title>Seitentitel</title>
</head>
<script>
let absatz1 = document.getElementById('bereich1');
console.log(absatz1.innerHTML);
console.log(absatz1);
</script>
<body>
    <h1>Überschrift 1</h1>
    <p id="bereich1">Erster Absatz mit Text</p>
    <p>Zweiter Absatz mit Text</p>	
    <a href="https://www.javascript-kurs.de/">Text des Links</a>
</script>
</body>
</html>

Woran liegt es? Unser JavaScript-Programm versucht über document.getElementById('bereich1'); auf einen Bereich in HTML zuzugreifen, der zu diesem Zeitpunkt noch gar nicht „angezeigt“ wird. Was ist damit gemeint? Unser Absatz mit der ID bereich1 wird erst später im Programm „ausgeführt“ und ist auch erst dann für JavaScript verfügbar.

Beweis für das bessere Verständnis

Wir können das auch sehr deutlich sichtbar machen, indem wir uns in der Konsole ausgeben lassen, was für JavaScript bisher vorhanden ist.

Über die Anweisung console.log(document.children[0].innerHTML); sehen wir den „Ladezustand“.

<html>
<head>
	<title>Seitentitel</title>
<script>
console.log(document.children[0].innerHTML);
window.addEventListener("load", function() {
	let absatz1 = document.getElementById('bereich1');
	// console.log(absatz1.innerHTML);
	// console.log(absatz1);
	console.log(document.children[0].innerHTML);
} );
</script>
</head>
<body>
	<h1>Überschrift 1</h1>
	<p id="bereich1">Erster Absatz mit Text</p>
	<p>Zweiter Absatz mit Text</p>	
	<a href="https://www.javascript-kurs.de/">Text des Links</a>
<script>
console.log(document.children[0].innerHTML);
</script>
</body>
</html>

Die Konsolenausgabe in Zeile 6 zeigt, dass nur der head-Bereich vorhanden ist – dagegen bekommen wir über den gleichen Befehl in der Konsolenausgabe den kompletten Code.

Unabhängig von Platzierung unseres JavaScript-Codes

Und genau hier wollen wir uns unabhängig machen.

Wir wollen unserem JavaScript-Programm sagen, dass es erst ausgeführt werden darf, wenn alle HTML-Elemente der Seite auch geladen worden sind.

EventListener – warten auf definierte Ereignisse mit JavaScript

Es gibt in JavaScript EventListener, die wir für Ereignisse wie einen Mausklick durch den Nutzer, Tastatureingaben oder auch das vollständige Laden aller HTML-Elemente einer Seite einsetzen können. Wir können also beliebig viele Events (englisch für Ereignis) abfragen, bzw. darauf warten und lauschen (engl. Listen), ob diese stattfinden. Richtig schön wird die deutsche Übersetzung von EventListener – es ist der Ereignis-Hörer.

Schauen wir uns den Aufbau in JavaScript an:

Die JavaScript-Anweisung startet mit window.addEventListener(). Unser Fenster wird also nach dem Starten unseres JavaScript-Programms permanent überwacht, ob ein bestimmtes Ereignis eintritt. Und hier liegt die Betonung auf permanent. Vergleich man dazu Programmiersprachen wie PHP, wo ein Programm ausgeführt wird und wenn dieses Programm an der letzten Code-Zeile angekommen ist, dieses auch abgeschlossen ist und fertig. Nutzen wir in JavaScript die EventListener, wird, sobald ein bestimmtes Ereignis (Event) eintritt dann der zugehörige Code in einer Funktion ausgeführt. Hier jetzt nicht über das neue Wort der Funktion stolpern – Funktionen werden noch eingeführt.

Jetzt müssen wir natürlich noch unserem addEventListener() mitgeben, auf welches Ereignis (Event) dieser lauschen soll:

window.addEventListener("load" );

Wir warten also das vollständige Laden unserer Datei ab – sprich, alle HTML-Anweisungen sind verfügbar und können durch JavaScript abgefragt bzw. genutzt werden. Unser Event "load" bedeutet also nichts anderes, als dass unsere komplette Seite fertig geladen ist.

Nun ist klar, wann unser EventListener aktiv werden soll – es fehlt nun die Aktivität. Schauen wir uns da erst den grundlegenden Aufbau ab:

window.addEventListener("load", function() {
} );

Und noch mit Aktion – es soll ausgegeben werden, dass die Seite komplett geladen wurde:

window.addEventListener("load", function() {
    console.log("Seite komplett geladen");
} );

Anstelle unserer Kontrollausgabe können hier zwischen den geschweiften Klammern natürlich beliebig viele JavaScript-Anweisungen stehen.

Aber nun erst noch der krönende Abschluss – aus historischen Gründen (hört sich immer gut an, meint aber, um keine Probleme mit alten Browsern zu bekommen) sollte nach der geschweiften Klammer immer noch ein false mitgegeben werden.

window.addEventListener("load", function() {
}, false );

Und nun können wir das anfangs problematische Beispiel in den neuen Bereich aufnehmen und alles ist gut:

<html>
<head>
	<title>Seitentitel</title>
</head>
<script>
window.addEventListener("load", function() {
    let absatz1 = document.getElementById('bereich1');
    console.log(absatz1.innerHTML);
    console.log(absatz1);
}, false );
</script>
<body>
    <h1>Überschrift 1</h1>
    <p id="bereich1">Erster Absatz mit Text</p>
    <p>Zweiter Absatz mit Text</p>	
    <a href="https://www.javascript-kurs.de/">Text des Links</a>
</body>
</html>

In den folgenden Tutorials werde ich immer mit dieser Konstruktion arbeiten, um diese Probleme zu vermeiden. Daher bitte immer nutzen – auch wenn in kommenden Beispielen unter Umständen der Übersichtlichkeit halber der addEventListener("load", …) nicht dargestellt ist.

Bitte unterstützen Sie dieses Projekt

Empfehlen Sie es weiter - wir freuen uns immer über Links und Facebook-Empfehlungen.

Bestellen Sie über folgenden Link bei Amazon:
Bücher über JavaScript

Sie können uns auch eine Spende über PayPal zukommen lassen.

Vielen Dank für Ihre Unterstützung

weitere eigene Projekte: