JavaScript/Tutorials/DOM/Einbindung in HTML
JavaScript ist eine Programmiersprache, die als Zusatztechnik in Webseiten eingebunden wird. Im modernen Webdesign erhalten Webseiten so neben der Inhaltsstruktur und dem Aussehen eine Verhaltensschicht.
Inhaltsverzeichnis
DOM-Scripting (Unobtrusive JavaScript)
JavaScript kommt in diesem Konzept die Aufgabe zu, dem Dokument »Verhalten« (Behaviour) hinzuzufügen. Damit ist gemeint, dass das Dokument auf gewisse Anwenderereignisse reagiert und z. B. Änderungen im Dokument vornimmt. Diese Interaktivität wird dem Dokument automatisch hinzugefügt – im HTML-Code sollte sich kein JavaScript in Form von Event-Handler-Attributen befinden (onload, onclick, onmouseover usw.). Im Idealfall steht im <head>
-Element das ein oder andere <script>
-Element, um eine externe JavaScript-Datei einzubinden, die dann ihrerseits aktiv wird und die Eventhandler an die jeweiligen Elemente anbringt. Dazu können Elemente, denen ein bestimmtes Verhalten hinzugefügt werden soll, z. B. mit einer Klasse markiert oder bei Bedarf sogar mit einer ID ausgezeichnet werden.
Zeitgemäße Scripte werden automatisch beim Laden des Dokuments aktiv und starten die Ereignisüberwachung an den betreffenden Elementen. Diese Anwendung von JavaScript nennt sich Unobtrusive JavaScript, »unaufdringliches« JavaScript, oder auch DOM Scripting.
Einbindung
JavaScript-Quelltexte werden in HTML in einem script-Element notiert oder referenziert. Das script
-Element darf dabei im body
oder head
des HTML-Dokuments notiert werden.
script-Elemente dürfen auch innerhalb von Flusselementen notiert werden.
Attribute im script
-Element
<script> … </script>
JavaScript Code direkt in HTML notieren
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript: Hallo Welt</title>
<script>
alert("Hallo Welt!");
</script>
<noscript>
Sie haben JavaScript deaktiviert.
</noscript>
</head>
<body>
<p>Diese Seite tut nichts weiter, als eine Hinweisbox auszugeben.</p>
</body>
</html>
noscript
können Sie Bereiche definieren, die angezeigt werden, wenn JavaScript deaktiviert ist.Früher war es üblich, Skripte in einen CDATA-Block einzuschließen. Die Notwendigkeit dafür bestand nur für XHTML Dokumente, wurde aber von vielen als „das muss so sein“ aufgefasst und überall eingesetzt. Es hat auch nicht gestört. Für HTML 5 gibt es zwar auch eine XML Notation, aber solange Sie ein solches Dokument nicht mit einem XML Tool verarbeiten wollen, ist die CDATA-Notation nicht mehr notwendig.
-->
zu verwenden. Der Versuch, einen solchen Script-Block mit einem HTML-Kommentar komplett auszublenden, führt dazu, dass der Kommentar dann bei dem -->
im Script endet.JavaScript-Dateien in HTML referenzieren
Das direkte Notieren von JavaScript in HTML ist im allgemeinen schlechte Praxis. Viel besser ist es, Scripte in eigenen Dateien zu notieren und diese dann einzubinden. Die Datei wird an der entsprechenden Stelle so ausgeführt, als ob der Code direkt notiert wurde. Sie können diese externen JavaScript-Dateien in beliebig viele Webseiten einbinden.
function Quadrat() {
var Eingabe = document.getElementById('Eingabe');
var Ergebnis = Eingabe.value * Eingabe.value;
alert("Das Quadrat von " + Eingabe.value + " = " + Ergebnis);
Eingabe.value = 0;
}
var los = document.getElementById('los');
los.addEventListener ('click', Quadrat, true);
Quadrat
, in der mit document.getElementById
auf das Eingabefeld zugegriffen wird. Der Variable Ergebnis
wird das Quadrat des Wertes der Eingabe zugewiesen. Dieses wird dann mit einer kurzen Erklärung ausgegeben. Der Wert der Eingabe wird dann zurückgesetzt.
In den letzten 2 Zeilen wird mit document.getElementById
mit der id los
auf den Button zugegriffen und ihm über addEventListener
der Event-Handler onclick
zugewiesen. Ein Klick auf den Button ruft die Funktion Quadrat
auf.
load
) durch eine Funktion aufgerufen werden.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>externes JavaScript in HTML einbinden</title>
</head>
<body>
<h1>externes JavaScript in HTML einbinden</h1>
<main>
<input type="number" id="Eingabe" value="0" size="3">
<button type="button" id="los">Quadrat errechnen</button>
</main>
<script src="quadrat.js"></script>
</body>
</html>
Das src-Attribut (source = "Quelle") hat als Wert den URI zum Script. (Mehr Informationen über Referenzieren in HTML)
document.body.addEventListener("load",test);
geladen werden.Script in den head oder ans Ende des body-Elements?
Eine immer wieder gestellte Frage ist, welche der beiden Positionen besser ist.
Wenn ein Browser eine Webseite lädt, folgt er einer festen Routine:
- Der Browser holt sich die HTML-Datei
- Das HTML-Markup wird geparst
- Der Parser trifft auf ein script-Element, das ein externes JavaScript referenziert
- Der Browser sendet einen Request, dass das Skript geladen werden soll. In der Zwischenzeit wird das Parsen des restlichen HTML-Markups eingestellt.
- Nach einiger Zeit ist das Skript heruntergeladen und wird ausgeführt.
- Der Browser setzt mit dem Parsen des restlichen HTML fort.
Warum kommt es bei Schritt 4 zu einer Unterbrechung? Skripte können mit document.write() oder anderen DOM-Manipulationen HTML einfügen oder verändern. Deshalb wartet der Parser, bis das Skript heruntergeladen und ausgeführt ist, bevor er den Rest des Dokuments parst.
Aus diesem Grund empfahlen früher viele JavaScript am Schluss einzubinden, indem das script-Element vor das schließende body-Tag gesetzt wurde. Dieser Ansatz birgt aber das Problem, dass der Browser Skripte erst downloaden kann, wenn das ganze HTML-Dokument geparst ist. Gerade bei größeren Seiten mit vielen Stylesheets, Skripten und eingebundenen Bibliotheken kann dies zu einer schlechteren Konversionsrate führen, wenn Nutzer nach erfolglosem Warten auf die Webseite entnervt aufgeben.
Also sollten Skripte so schnell wie möglich geladen werden.
Fazit: in den head
Durch die Attribute async und defer können Sie dem Browser mitteilen, dass er mit dem Parsen fortfahren kann, während er Skripte herunterlädt.
Details: caniuse.com
<script src="script1.js" async></script>
<script src="script2.js" async></script>
Auch auf den wenigen alten Browsern, die diese Attribute noch nicht unterstützen, werden Ihre Seiten korrekt geladen.
Sie müssen beim Gebrauch von async und defer jedoch die Verarbeitungsreihenfolge des Browsers im Auge behalten.
Inline-Scripte ohne type="module"
sowie externe Scripte, die kein async
- oder defer
-Attribut haben, halten die Verarbeitung des HTML Dokuments an und werden in dem Moment, wo sie angetroffen werden, ausgeführt. Bei externen Scripten kann das zunächst einen Serverzugriff bedeuten, wenn sie nicht im Cache stehen, und eine merkliche Verzögerung auslösen.
Alle anderen Scripte werden in eine Warteschlange gestellt. Ist das Script extern und nicht im Cache, fordert der Browser es vom Server an.
Nachdem das Dokument geladen ist, beginnt das Abarbeiten der Warteschlange. Die mit defer
eingestellten Scripte werden strikt in der Reihenfolge abgearbeitet, in der sie eingestellt wurden, ganz gleich, in welcher Reihenfolge der Server sie geliefert hat. Erst nach dem letzten defer
-Script wird das DOMContentLoaded
Event signalisiert.
Die mit async
eingestelltes Scripte werden in der Reihenfolge ausgeführt, wie sie verfügbar werden. Das kann vor dem ersten defer
-Script sein, zwischen zwei defer
-Scripten oder auch erst nach dem letzten defer
-Script.
Das bedeutet:
- Scripte ohne
defer
oderasync
werden immer vor demDOMContentLoaded
Event ausgeführt. Ein Handler für dasDOMContentLoaded
Event, den Sie in einemdefer
-Script registrieren, wird definitiv ausgeführt. - Auch die
defer
-Scripte laufen immer vor demDOMContentLoaded
Event. Ein Handler für dasDOMContentLoaded
Event, den Sie in einem solchen Script registrieren, wird definitiv ausgeführt. - Ein
async
-Script kann vorher oder nachher ausgeführt werden. Ein Handler für dasDOMContentLoaded
Event wird aber nur dann ausgeführt, wenn dasasync
-Script rechtzeitig verfügbar war. Sie können die EigenschaftreadyState
desdocument
-Objekts verwenden, um in einemasync
-Script festzustellen, obDOMContentLoaded
bereits ausgelöst wurde. Enthält sie den Wert'loading'
, stehtDOMContentLoaded
noch bevor, andernfalls ist es bereits vorbei. - Aber Vorsicht: Ein Alt-Browser, der
async
oderdefer
nicht unterstützt, lädt das Script dann, wenn er es antrifft, und führt es sofort aus. Solche Browser unterstützen aber eventuell auch diereadyState
Eigenschaft des Dokuments nicht, bzw. die Internet Explorer Versionen 9 und 10 können einen falschen readyState melden. Wenn Sie von der Existenz von DOM Objekten abhängig sind, versuchen Sie in Ihrem Script, eins davon zu finden. Fehlt es noch, registrieren Sie Ihre Logik in einem DOMContentLoaded Handler.
registriereClickHandler
gebündelt. Der Vorspann des Scripts prüft zunächst, ob der Button bereits zu finden ist. Wenn ja, ruft er die Registrierfunktion direkt auf. Andernfalls wird sie als EventHandler für DOMContentLoaded registriert.if (document.getElementById("speichernButton"))
registriereClickHandler()
else
document.addEventListener("DOMContentLoaded", registriereClickHandler);
function registriereClickHandler() {
document.getElementById("speichernButton")
.addEventListener("click", function(event) {
// Code zum Speichern hier
});
}
Hinweis
head
einbinden, da im body
vorhandene Skripte im Frickl-Editor zwar angezeigt, beim Ausführen durch den im HTML-Markup vorhandenen OriginalCode aber wieder überschrieben werden.
--MScharwies (Diskussion) 11:55, 11. Jan. 2017 (CET)
Weblinks
- stackoverflow: Where is the best place to put <script> tags in HTML markup?
- Google.developers: JavaScript-Code entfernen, der das Rendern blockiert
- html5rocks: Deep dive into the murky waters of script loading von Jake Archibald
(sehr ausführlicher Artikel, der anschaulich erklärt, wie JavaScript im Browser geladen und ausgeführt wird)