Das laden von javascript async, dann überprüfen DOM geladen, bevor Sie ausgeführt Rückruf
Problem:
Laden js-Dateien asynchron, dann überprüfen Sie, um zu sehen, wenn das dom geladen ist, bevor der Rückruf aus dem laden der Dateien wird ausgeführt.
edit: Wir nicht jQuery verwenden; verwenden wir Prototypen.
edit: mehr Kommentare zu dem code-Beispiel.
Hey Leute,
Ich versuche zu laden, alle meine js-Dateien asynchron so zu gestalten, dass Sie von der Sperrung der rest der Seite. Aber wenn die Skripte geladen und der callback aufgerufen wird, muss ich wissen, wenn das DOM geladen wurde oder nicht, damit ich weiß wie die Struktur der Rückruf. Siehe unten:
//load asynchronously
(function(){
var e = document.createElement('script');
e.type = "text/javascript";
e.async = true;
e.src = srcstr;
//a little magic to make the callback happen
if(navigator.userAgent.indexOf("Opera")){
e.text = "initPage();";
}else if(navigator.userAgent.indexOf("MSIE")){
e.onreadystatechange = initPage;
}else{
e.innerHTML = "initPage();";
}
//attach the file to the document
document.getElementsByTagName('head')[0].appendChild(e);
})();
initPageHelper = function(){
//requires DOM be loaded
}
initPage = function(){
if(domLoaded){ //if dom is already loaded, just call the function
initPageHelper();
}else{ //if dom is not loaded, attach the function to be run when it does load
document.observe("dom:loaded", initPageHelper);
}
}
Callback aufgerufen wird, richtig durch einige Magie, hinter den kulissen, erfahren Sie von dieser Google-talk: http://www.youtube.com/watch?v=52gL93S3usU&feature=related
Was ist der einfachste, cross-browser-Methode, zu Fragen, wenn das DOM geladen wurde, bereits?
BEARBEITEN
Hier ist die komplette Lösung, die ich ging mit.
Ich habe den Prototyp und die asynchrone script-loader mit der normalen Methode. Das Leben ist einfach so viel einfacher mit Prototypen, so bin ich bereit, block für das Skript.
<script type="text/javascript" src="prototype/prototype.js"></script>
<script type="text/javascript" src="asyncLoader.js"></script>
Und tatsächlich, in meinem code, den ich minified die beiden oben genannten Dateien und steckte Sie zusammen in einer Datei zu minimieren übertragen und http-Anforderungen.
Dann definiere ich, was ich will ausführen, wenn das DOM geladen, und rufen Sie dann die Funktion zum laden von anderen Skripten.
<script type="text/javascript">
initPage = function(){
...
}
</script>
<script type="text/javascript">
loadScriptAsync("scriptaculous/scriptaculous.js", initPage);
loadScriptAsync("scriptaculous/effects.js", initPage);
loadScriptAsync("scriptaculous/controls.js", initPage);
...
loadScriptAsync("mypage.js", initPage);
</script>
Ebenso die Anforderungen oben sind tatsächlich komprimiert in einem httpRequest mit einem minifier. Sie trennen hier für die Lesbarkeit. Es ist ein Ausschnitt an der Unterseite von diesem post zu zeigen, was der code aussieht mit den minifier.
Den code für asyncLoader.js ist die folgende:
/**
* Allows you to load js files asynchronously, with a callback that can be
* called immediately after the script loads, OR after the script loads and
* after the DOM is loaded.
*
* Prototype.js must be loaded first.
*
* For best results, create a regular script tag that calls a minified, combined
* file that contains Prototype.js, and this file. Then all subsequent scripts
* should be loaded using this function.
*
*/
var onload_queue = [];
var dom_loaded = false;
function loadScriptAsync(src, callback, run_immediately) {
var script = document.createElement('script');
script.type = "text/javascript";
script.async = true;
script.src = src;
if("undefined" != typeof callback){
script.onload = function() {
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
//clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
};
script.onreadystatechange = function() {
if (script.readyState == 'complete'){
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
//clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
}else if(script.readyState == 'loaded'){
eval(script);
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
//clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
}
};
}
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
}
document.observe("dom:loaded", function(){
dom_loaded = true;
var len = onload_queue.length;
for (var i = 0; i < len; i++) {
onload_queue[i]();
}
onload_queue = null;
});
Ich die option Hinzugefügt, um ein Skript auszuführen, sofort, wenn Sie Skripts, verlassen Sie sich nicht auf die Seite DOM vollständig geladen ist.
Die minified-Anforderungen tatsächlich Aussehen:
<script type="text/javascript" src="/min/?b=javascript/lib&f=prototype/prototype.js,asyncLoader.js"></script>
<script type="text/javascript"> initPage = function(e){...}</script>
<script type="text/javascript">
srcstr = "/min/?f=<?=implode(',', $js_files)?>";
loadScriptAsync(srcstr, initPage);
</script>
Sind Sie mit dem plugin aus: http://code.google.com/p/minify/
Danke für die Hilfe!!
-K
- Ich möchte die jQuery ' s $(document).ready () - event. Einfachste, cross-browser-Weise, die ich kenne.
- Können Sie eine Flagge, die Sie festlegen können, wenn DOM geladen ist, und überprüfen Sie, dass die Flagge in Ihren Rückruf fn.
- Sie können markieren Sie eine Antwort als angenommen, wenn Ihr problem gelöst wurde.
- sorry @galambalazs, habe ich markiert es jetzt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was Sie brauchen, ist eine einfache Warteschlange von
onload
Funktionen. Bitte auch vermeiden Sie browser-sniffing wie es instabil ist und nicht zukunftsfähig. Für den vollständigen Quellcode finden Sie in der [Demo]Test-Nutzung
dom:loaded
auch jQuery verwendet eine modifizierte version dieser.Können Sie immer Ihre erste loader-Skript an der Unterseite, direkt vor dem schließenden body-tag.