Okay, dies könnte nur eine dumme Frage sein, obwohl ich bin sicher, es gibt viele andere Menschen, die die gleiche Frage von Zeit zu Zeit. Ich, ich möchte nur 100% sicher über es so oder so zu machen. Mit jQuery kennen wir alle die wunderbare
$('document').ready(function(){});
Angenommen, ich möchte eine Funktion ausführen, die in Standard-JavaScript geschrieben ist, ohne dass sie von einer Bibliothek unterstützt wird, und ich möchte eine Funktion starten, sobald die Seite bereit ist, sie zu verarbeiten. Was ist der richtige Weg, um dies zu tun?
Ich weiß, dass ich das kann:
window.onload="myFunction()";
...oder ich kann den "body"-Tag verwenden:
<body onload="myFunction()">
...oder ich kann sogar versuchen, am Ende der Seite nach allem, aber dem Ende des body
oder html
Tags wie:
<script type="text/javascript">
myFunction();
</script>
Was ist eine Cross-Browser (alt/neu) konforme Methode, um eine oder mehrere Funktionen in einer Art und Weise wie jQuery's $.ready()
auszuführen?
In Ermangelung eines Frameworks, das die Cross-Browser-Kompatibilität für Sie übernimmt, ist es am einfachsten, am Ende des Body einen Aufruf an Ihren Code zu setzen. Dies ist schneller als ein "onload"-Handler, da dieser nur darauf wartet, dass das DOM bereit ist, und nicht darauf, dass alle Bilder geladen werden. Außerdem funktioniert dies in jedem Browser.
<!doctype html>
<html>
<head>
</head>
<body>
Your HTML here
<script>
// self executing function here
(function() {
// your page initialization code here
// the DOM will be available here
})();
</script>
</body>
</html>
Für moderne Browser (alles ab IE9 und neuer und jede Version von Chrome, Firefox oder Safari), wenn Sie in der Lage sein wollen, eine jQuery-ähnliche $(document).ready()
-Methode zu implementieren, die Sie von überall aus aufrufen können (ohne sich Gedanken darüber zu machen, wo das aufrufende Skript positioniert ist), können Sie einfach etwas wie dieses verwenden:
function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
Verwendung:
docReady(function() {
// DOM is loaded and ready for manipulation here
});
Wenn Sie volle Cross-Browser-Kompatibilität benötigen (einschließlich alter IE-Versionen) und nicht auf window.onload
warten wollen, dann sollten Sie sich ansehen, wie ein Framework wie jQuery seine Methode $(document).ready()
implementiert. Das ist ziemlich kompliziert und hängt von den Fähigkeiten des Browsers ab.
Um Ihnen eine kleine Vorstellung davon zu geben, was jQuery tut (was überall funktioniert, wo das Skript-Tag platziert ist).
Wenn es unterstützt wird, versucht es den Standard:
document.addEventListener('DOMContentLoaded', fn, false);
mit einem Fallback zu:
window.addEventListener('load', fn, false )
oder für ältere Versionen des IE, verwendet es:
document.attachEvent("onreadystatechange", fn);
mit einem Fallback zu:
window.attachEvent("onload", fn);
Und es gibt einige Workarounds im IE-Codepfad, denen ich nicht ganz folgen kann, aber es sieht so aus, als hätte es etwas mit Frames zu tun.
Hier ist ein vollständiger Ersatz für jQuery's .ready()
geschrieben in plain javascript:
(function(funcName, baseObj) {
// The public function name defaults to window.docReady
// but you can pass in your own object and own function name and those will be used
// if you want to put them in a different namespace
funcName = funcName || "docReady";
baseObj = baseObj || window;
var readyList = [];
var readyFired = false;
var readyEventHandlersInstalled = false;
// call this when the document is ready
// this function protects itself against being called more than once
function ready() {
if (!readyFired) {
// this must be set to true before we start calling callbacks
readyFired = true;
for (var i = 0; i < readyList.length; i++) {
// if a callback here happens to add new ready handlers,
// the docReady() function will see that it already fired
// and will schedule the callback to run right after
// this event loop finishes so all handlers will still execute
// in order and no new ones will be added to the readyList
// while we are processing the list
readyList[i].fn.call(window, readyList[i].ctx);
}
// allow any closures held by these functions to free
readyList = [];
}
}
function readyStateChange() {
if ( document.readyState === "complete" ) {
ready();
}
}
// This is the one public interface
// docReady(fn, context);
// the context argument is optional - if present, it will be passed
// as an argument to the callback
baseObj[funcName] = function(callback, context) {
if (typeof callback !== "function") {
throw new TypeError("callback for docReady(fn) must be a function");
}
// if ready has already fired, then just schedule the callback
// to fire asynchronously, but right away
if (readyFired) {
setTimeout(function() {callback(context);}, 1);
return;
} else {
// add the function and context to the list
readyList.push({fn: callback, ctx: context});
}
// if document already ready to go, schedule the ready function to run
if (document.readyState === "complete") {
setTimeout(ready, 1);
} else if (!readyEventHandlersInstalled) {
// otherwise if we don't have event handlers installed, install them
if (document.addEventListener) {
// first choice is DOMContentLoaded event
document.addEventListener("DOMContentLoaded", ready, false);
// backup is window load event
window.addEventListener("load", ready, false);
} else {
// must be IE
document.attachEvent("onreadystatechange", readyStateChange);
window.attachEvent("onload", ready);
}
readyEventHandlersInstalled = true;
}
}
})("docReady", window);
Die neueste Version des Codes ist öffentlich auf GitHub unter https://github.com/jfriend00/docReady verfügbar.
Verwendung:
// pass a function reference
docReady(fn);
// use an anonymous function
docReady(function() {
// code here
});
// pass a function reference and a context
// the context will be passed to the function as the first argument
docReady(fn, context);
// use an anonymous function with a context
docReady(function(context) {
// code here that can use the context argument that was passed to docReady
}, ctx);
Dies wurde getestet in:
IE6 and up
Firefox 3.6 and up
Chrome 14 and up
Safari 5.1 and up
Opera 11.6 and up
Multiple iOS devices
Multiple Android devices
Arbeitsimplementierung und Prüfstand:
Hier ist eine Zusammenfassung, wie es funktioniert:
docReady(fn, context)
docReady(fn, context)
aufgerufen wird, prüfen Sie, ob der ready handler bereits ausgelöst wurde. Wenn ja, planen Sie einfach den neu hinzugefügten Callback so, dass er direkt nach Beendigung dieses Threads von JS mit setTimeout(fn, 1)
ausgelöst wird.document.addEventListener
existiert, dann installiere Ereignis-Handler mit .addEventListener()
für beide "DOMContentLoaded"
und "load"
Ereignisse. Das "load"-Ereignis ist ein Backup-Ereignis zur Sicherheit und sollte nicht benötigt werden.document.addEventListener
nicht existiert, dann installieren Sie Event-Handler mit .attachEvent()
für "onreadystatechange"
und "onload"
Events.onreadystatechange
-Ereignis prüfen, ob der document.readyState === "complete"
ist und wenn ja, eine Funktion aufrufen, um alle ready-Handler auszulösen.Handler, die mit docReady()
registriert wurden, werden garantiert in der Reihenfolge abgefeuert, in der sie registriert wurden.
Wenn Sie docReady(fn)
aufrufen, nachdem das Dokument bereits fertig ist, wird der Callback so geplant, dass er ausgeführt wird, sobald der aktuelle Thread der Ausführung mit setTimeout(fn, 1)
beendet ist. Dies erlaubt es dem aufrufenden Code, immer davon auszugehen, dass es sich um asynchrone Rückrufe handelt, die später aufgerufen werden, auch wenn später ist, sobald der aktuelle Thread von JS beendet ist, und es bewahrt die Aufrufreihenfolge.
Ihre Methode (Platzierung des Skripts vor dem schließenden Body-Tag)
<script>
myFunction()
</script>
</body>
</html>
ist eine zuverlässige Methode, um alte und neue Browser zu unterstützen.
Die Option document.ondomcontentready=function(){}
sollte ausreichen, ist aber nicht vollständig browserfähig.
Scheint, als sollten Sie nur jQuery min verwenden