Mehrere Onload-Ereignisse nutzen
Internetseite initialisieren
JavaScript, resp. jQuery mit dem entsprechenden Wrapper, ermöglicht ein komfortables Reagieren auf ein fertig geladenes Dokument/DOM.
Ist der komplette Inhalt einer Internetseite geladen, wird das Onload-Ereigniss getriggert und es können diverse Modifikationen am DOM vorgenommen werden.
// Pures JavaScript: window.onload = function() { /*...*/ }; // jQuery-Style: $(document).ready(function() { /*...*/ });
Nun sah ich mich während der Implementierung der neusten Version meines Blogs einmal mehr mit dem Problem konfrontiert, dass ich an mehreren Stellen meines Codes (insbesondere in verschiedenen .js-Dateien) auf das Onload-Ereigniss reagieren können musste.
Überschreiber
Benutzt man einfach wieder eines der oben erwähnten Code-Snippets, wird die vorher definierte Callback-Methode mit der neuen überschrieben und somit nicht mehr ausgeführt.
$(document).ready(function() { alert("Erste call-back-methode"; }); $(document).ready(function() { alert("Zweite call-back-methode: Ha! Ich hab' die erste überschrieben!"; });
Die Idee
Die zugrundeliegende Idee wie dieses Problem umgangen werden kann ist eigentlich recht simpel:
- Alle Callback-Methoden, welche nach dem Laden des Dokuments ausgeführt werden sollen, werden in einem Array abgelegt. Diese werden nun als Onload-Handler bezeichnet.
- Dem onload-Ereigniss wird eine neue Callback-Methode zugewiesen. Diese durchläuft das Array mit allen Onload-Handlern und ruft diese einen nach dem anderen auf.
Kompliziert? Überhaupt nicht. Folgender Absatz zeigt eine Beispielimplementierung.
Framework-Code
Mit wenigen Zeile Code kann ein kleines Framework zum verwalten mehrerer Onload-Handler implementiert werden.
var onloadHandlers = new Array(); /** * Fügt einen neuen onloadHandler am Ende der aktuellen * Handler-Liste hinzu. * * @param onloadHandler * @author Manuel Alabor, http://www.msites.net/ */ function appendOnloadHandler(onloadHandler) { onloadHandlers.push(onloadHandler); } /** * Fügt einen neuen onloadHandler am Anfang der aktuellen * Handler-Liste hinzu. * * @param onloadHandler * @author Manuel Alabor, http://www.msites.net/ */ function prependOnloadHandler(onloadHandler) { onloadHandlers.unshift(onloadHandler); } /** * Sobald das aktuelle Dokumenten-DOM bereit ist, werden alle * vorhandenen onloadHandlers der Reihe nach ausgeführt. * * @author Manuel Alabor, http://www.msites.net/ */ $(document).ready(function() { for(var i = 0, l = onloadHandlers.length; i < l; i++) { onloadHandlers[i](); } });
Beispiel eines Handlers
Um den praktischen Nutzen zu demonstrieren möchte ich hier gleich auch einen einfachen Onload-Handler vorstellen.
Seine Funktion: Führt das href-Attribut eines beliebigen Links auf eine externe Seite resp. beginnt nicht mit http://www.msites.net, wird das target-Attribut auf _blank gesetzt um das Ziel in einem neuen Fenster zu öffnen.
Abschliessend wird er Onload-Handler per appendOnloadHandler() aktiviert.
/** * Verändert alle externen Links so, dass sie in einem neuen * Fenster geöffnet werden (target = _blank) * * @author Manuel Alabor, http://www.msites.net/ */ function externalLinksInBlank() { /* Allgemeine Links anpassen: */ $("a").each(function() { // Extern -> Neues Fenster var href = $(this).attr("href"); if(href != undefined) { if(href.substring(0,21) != "http://www.msites.net") $(this).attr("target", "_blank"); } }); } appendOnloadHandler(externalLinksInBlank); // onloadHandler hinzufügen
Um zusätzliche Onload-Handler auszuführen werden diese genau gleich wie hier im Beispiel als Methode implementiert und anschliessend per appendOnloadHandler() resp. prependOnloadHandler() dem Framework hinzugefügt.
Simpel, oder?
Nur mit jQuery?
Der oben vorgestellte Code benutzt die freie Library jQuery.
Das Framework (nicht der Beispiel-Handler!) kann jedoch mit einer kleinen Anpassung auch komplett ohne die Bibliothek verwendet werden.
/** * Sobald das aktuelle Dokumenten-DOM bereit ist, werden alle * vorhandenen onloadHandlers der Reihe nach ausgeführt. * -> jQuery-freie Version * * @author Manuel Alabor, http://www.msites.net/ */ window.onload = function() { for(var i = 0, l = onloadHandlers.length; i < l; i++) { onloadHandlers[i](); } };