Vor kurzem schreibe ich ein JavaScript -Framework. Ich habe gerade das Domcontent -Ereignis eingekapselt und war ein wenig aufgeregt. Ich machte mir Notizen zu den Prinzipien und Kompatibilitätsproblemen, die während des Entwicklungsprozesses auftreten, um nicht überall zu vergessen.
Wenn wir JS -Code schreiben, fügen wir in der Regel ein Fenster hinzu.onload Ereignis, hauptsächlich, um GetElementById zu verwenden. Das Fenster ist jedoch warten, bis das DOM, das Skript, das CSS geladen und alle Ressourcen im Bild oder sogar Iframe ausgelöst werden. In vielen Fällen hat die Webseite mehr Bilder und ist größer. Es dauert lange, bis das Bild geladen wird, und es ist offensichtlich zu spät, JS auszuführen, was sich häufig auf die Benutzererfahrung auswirkt.
Viele JS -Frameworks verfügen über eine Dokument.
Der Kern des Dokuments.Ready ist das Domcontent -Ereignis. Firefox, Chrome, Opera, Safari und IE9+ können AddEventListener ('Domcontentled', Fn, False) zur Ereignisbindung verwenden. IE6 ~ 8 unterstützt das Domcontent -Ereignis nicht, sodass die Kompatibilitätsverarbeitung für IE6 ~ 8 durchgeführt werden sollte.
In den Informationen heißt es, dass IE6 ~ 8 das Dokument verwenden kann.onReadyStatEchange -Ereignis, um zu hören, ob das Dokument. Wenn ein Iframe in die Seite eingebettet ist, wartet das Dokument. Zu diesem Zeitpunkt wird der Iframe zum zeitaufwändigen Hauptbenutzer. Aber nach dem Testen, selbst wenn auf der Seite kein Iframe vorhanden ist, wird das Onload -Ereignis bei der Vervollständigung von ReadyState tatsächlich anstelle des Domcontent -Ereignisses ausgelöst, was bis zu diesem Punkt überraschend ist.
Glücklicherweise hat der IE eine einzigartige Doscroll -Methode. Wenn der Seiten -DOM nicht geladen ist, wird ein Fehler gemeldet, wenn die DOSCROLL -Methode aufgerufen wird. Umgekehrt bedeutet Doscroll in Intervallen, bis kein Fehler gemeldet ist, dies bedeutet, dass die Seitendom geladen wurde. Diese Methode ist gültig, unabhängig davon, ob der Inhalt im Bild und Iframe geladen wurde.
Wenn mehrere JS -Dateien an das Dokument gebunden sind.
Das obige ist das Prinzip- und Kompatibilitätsproblem des Dokuments. Das Folgende ist ein Absatz von Beispielcode. Um das Verständnis des Ausführungsprozesses zu erleichtern, wird der Ausführungsprozess in den Kommentaren unter Verwendung des Funktionsverkapselungsmodus geschrieben. Wenn es Unangemessenheit gibt, geben Sie mir bitte einige Ratschläge.
Die Codekopie lautet wie folgt:
// Speichern Sie die Ereigniswarteschlange von Domready
eventQueue = [];
// Beurteile, ob das DOM geladen wurde
isReady = false;
// beurteilen, ob domready gebunden ist
isBind = false;
/*Domready () ausführen
*
*@param {function}
*@Execute drückt den Ereignishandler in die Ereigniswarteschlange und bindet Domcontentled
* Wenn die DOM -Belastung abgeschlossen ist, führen Sie sofort aus
*@Anrufer
*/
Funktion domready (fn) {
if (isReady) {
fn.call (Fenster);
}
anders{
eventQueue.push (fn);
};
Bindready ();
};
/*Domready Ereignisbindung
*
*@param null
*@Execute moderne Browser binden Domcontent, der über AddevListener geladen wurde, einschließlich IE9+
IE6-8 bestimmt, ob das DOM durch die Beurteilung von DOSCROLL geladen wurde
*@Caller domready ()
*/
Funktion Bindready () {
Wenn (isReady) zurückkehren;
wenn (isbind) zurückkehren;
isBind = true;
if (window.addeventListener) {
document.adDeVentListener ('domcontentled', execfn, false);
}
sonst if (window.attachEvent) {
doscroll ();
};
};
/*doscroll bestimmt, ob das DOM von IE6-8 geladen wurde.
*
*@param null
*@Execute doscroll bestimmt, ob das DOM geladen wird
*@Caller BindReady ()
*/
Funktion doscroll () {
versuchen{
document.documentElement.doscroll ('links');
}
fangen (Fehler) {
return setTimeout (doscroll, 20);
};
execfn ();
};
/*Ausführung Ereigniswarteschlange
*
*@param null
*@Execute Loop Execution Event -Handler in der Warteschlange ausführen
*@Caller BindReady ()
*/
Funktion execfn () {
if (! isReady) {
isReady = wahr;
für (var i = 0; i <eventQueue.length; i ++) {
EventQueue [i] .Call (Fenster);
};
eventQueue = [];
};
};
// JS -Datei 1
domready (function () {
...
});
// JS -Datei 2
domready (function () {
...
});
// Beachten Sie, dass die Funktion nicht ausgeführt wird, wenn es asynchron geladen wird, die domreadische Methode nicht binden.
// Weil vor dem Download des asynchronen Ladens JS, DomcontentLode, abgefeuert wurde und der AddEventListener bei der Ausführung nicht angehört werden kann
Testseite: Zwei große Bilder werden geladen. Bei Onload muss das Bild geladen werden, bevor JS ausgeführt werden kann. DomContentLodeed muss nur warten, bis das DOM geladen ist, um JS auszuführen. Sie können Firebug öffnen, um den Ladevorgang anzuzeigen. Denken Sie daran, den Browser -Cache vor jedem Test zu reinigen.