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.
InformationsquelleAutor Ken | 2010-11-22
Schreibe einen Kommentar