2013-02-11 13 views
30

Dodałem atrybuty async do kodu HTML włącznika javascript.
Więc teraz mam:Załaduj jQuery asynchronicznie przed innymi skryptami.

<script async src="jquery.myscript.js"></script> 

I to działa ze wszystkimi obciążenia JS I, wszystkie z wyjątkiem jQuery.

Jeśli dodaję async do znacznika jQuery <script>, wszystkie pozostałe skrypty zależne od jquery nie będą działać.

W tym jsfiddle widać problem:
http://jsfiddle.net/uFbdV/

W przykładzie używałem <script> Mycode </script> zamiast tym zewnętrznym file.js, ale to nie zmienia sytuacji.

Chciałbym uruchomić jQuery z async attrib i uruchamiać kilka innych zewnętrznych skryptów asynchronicznie tylko po załadowaniu jquery.

Jest to możliwe?

+0

może być konieczne użycie 'async =" "' zamiast 'async' sam. na przykład mój szablon blogger.com wymagał '=" "' – noobninja

Odpowiedz

20

Chciałbym uruchomić jQuery z asynchronicznym attrib i uruchomić kilka innych zewnętrznych skrypty asynchronicznie tylko po jQuery jest załadowany.

Co to oznacza? Brzmi to tak, jakbyś chciał najpierw załadować jQuery, a potem inne rzeczy, kiedy to się skończy. Więc chcesz go załadować synchronicznie. Jeśli nadal chcesz korzystać z metody async, możesz zdefiniować funkcję onload, aby kontynuować ładowanie innych rzeczy, gdy jQuery będzie gotowe. Lub możesz użyć defer. Obie te są opisane tutaj: https://davidwalsh.name/html5-async

+10

Chciałbym załadować wszystkie skrypty asynchronicznie, ale uruchom je we właściwej kolejności. –

+0

Rozszerzyłem swoją odpowiedź, zastanawiając się, jak to zrobić. –

+0

, więc nie musisz niczego implementować w funkcji myInit()? – csandreas1

12

To może być to, czego szukasz:
http://www.yterium.net/jQl-an-asynchronous-jQuery-Loader - jQl asynchronicznego jQuery Loader.

To asynchronicznie wczytuje jQuery bez blokowania innych komponentów:

jQl.loadjQ('http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'); 

jQl automatycznie łapie wszystkie jQuery().ready() połączeń, dzięki czemu można napisać:

<script type="text/javascript"> 
    jQl.loadjQ('http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'); 
    jQuery('document').ready(function(){ 
    alert('Hello world'); 
    }); 
</script> 

jQl będzie kolejce tych wywołań funkcji i wykonać je jako wkrótce po załadowaniu jQuery i DOM jest gotowy, ponieważ będą one wykonywane w zwykły sposób.

11

To wielki use-case dla defer:

<script defer src="jquery.js"></script> 
<script defer src="custom.js"></script> 

Żadna z tych tagów zablokuje rendering. Przeglądarka może pobierać równolegle jquery.js i custom.js. Wykona on jquery.js zaraz po pobraniu, a DOM został załadowany, a następnie zostanie wykonany.

Niestety, istnieje kilka problemów:

  • Nie można użyć atrybutu defer dla skryptów inline.
  • IE < 10 zostało udokumentowane jako powodujące skrypty z defer na unexpectedly interleave their execution.
  • Nie mogę znaleźć żadnych specyfikacji, które mówią, że skrypty z zamówieniem defer mają być wykonywane w kolejności, tylko że mają być wykonane po wczytaniu DOM.
-1
<script>var JSdep = [ 
     ["//ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.4.min.js", "window.jQuery", "/bundle/jquery"], 
     ["//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js", "self.framework === 'bootstrap'", "/bundle/bootstrap"], 
     ["//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js", "window.jQuery && window.jQuery.ui && window.jQuery.ui.version === '1.12.1'", "/bundle/jqueryui"], 
     ["//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js", "window.jQuery && window.jQuery.fn.selectpicker", "/bundle/bootstrap-select"], 
    ] 
</script> 
<script type="text/javascript"> 
    var downloadJSAtOnload = function (e) { 
     var src = e.srcElement.src.toString(); 
     //console.log("[jquery] loaded", src); 
     for (var i = 0; i < JSdep.length; i++) { 
      if (src.indexOf(JSdep[i][0]) !== -1) { 
       if ((!JSdep[i][1]) || (eval(JSdep[i][1]))) { 
        console.log("[jquery] loaded ok", src); 
        break; 
       } else { 
        console.log("[jquery] fail", src); 
        return; 
       } 
      } 
     } 
     if (i === JSdep.length) { 
      console.log("[jquery] fallback loaded ok", src); 
     } 
     if (jqloaded) { 
      return; 
     } 
     jqloaded = true; 
     for (var i = 1; i < JSdep.length; i++) { 
      //console.log("[jquery] loading", JSdep[i][0], JSdep[i][1], JSdep[i][2]); 
      var raf2 = requestAnimationFrame || mozRequestAnimationFrame || 
       webkitRequestAnimationFrame || msRequestAnimationFrame; 
      if (raf2) { window.setTimeout(dljquery([JSdep[i][0], JSdep[i][1], JSdep[i][2]]), 0); } 
      else window.addEventListener('load', dljquery([JSdep[i][0], JSdep[i][1], JSdep[i][2]])); 
     } 
    } 
    var downloadJSAtOnerror = function (e) { 
     var src = e.srcElement.src.toString(); 
     console.log("[jquery] error", src); 
     for (var i = 0; i < JSdep.length; i++) { 
      if (src.indexOf(JSdep[i][0]) !== -1) { 
       console.log("[jquery] failed try fallback", src); 
       dljquery([JSdep[i][2], JSdep[i][1]]); 
       return; 
      } 
     } 
     console.log("[jquery] failed on fallback", src); 
     return; 
    } 
    // Add a script element as a child of the body 
    var dljquery = function (src) { 
     //console.log("[jquery] start", src); 
     var element = document.createElement("script"); 
     element.src = src[0]; 
     element.async = "async"; 
     try { 
      document.body.appendChild(element); 
     } catch (err) { 
      console.log("[jquery] err", err); 
     } 
     if (element.addEventListener) { 
      element.addEventListener("load", downloadJSAtOnload, false); 
      element.addEventListener("error", downloadJSAtOnerror, false); 
     } else if (element.attachEvent) { 
      element.attachEvent("onload", downloadJSAtOnload); 
      element.attachEvent("onerror", downloadJSAtOnerror); 
     } else { 
      element.onload = downloadJSAtOnload; 
      element.onerror = downloadJSAtOnerror; 
     } 
    } 
    //  var fb = "/bundle/jquery"; 

    var raf = requestAnimationFrame || mozRequestAnimationFrame || 
     webkitRequestAnimationFrame || msRequestAnimationFrame; 
    if (raf) raf(function() { window.setTimeout(dljquery([JSdep[0][0], JSdep[0][1], JSdep[0][2]]), 0); }); 
    else window.addEventListener('load', dljquery([JSdep[0][0], JSdep[0][1], JSdep[0][2]])); 

    var jqloaded = false; 

    function doOnload() { 
     console.log("[jquery] onload"); 
    } 
    // Check for browser support of event handling capability 
    if (window.addEventListener) 
     window.addEventListener("load", doOnload, false); 
    else if (window.attachEvent) 
     window.attachEvent("onload", doOnload); 
    else window.onload = doOnload; 
</script> 

okazało miałem problemy z mnóstwem bootstrapowych czasami przed jQuery teraz NP nadzieję, że to pomaga innym kładę ten skrypt na głowie, ale dał błąd cant appendChild teraz jej przed /body i sprawdzone działa we wszystkich przeglądarkach i wypróbowałem skrypt async ale nie było zdarzenia informującego o tym, kiedy pobieranie kończy się i czasami ładowanie bootstrap przed jquery i vice versa ponieważ bootstrap zależy od jquery musiałem załadować jquery, a następnie uruchomić pobrania bootstrap teraz dodam awaryjna

naprawił

teraz sprawdza czy JQ ładowane

a dopiero potem ładuje inni

ok teraz jego kopia wklej

0

Ta funkcja jest inteligentna dla javascript asynchronicznie załadować:

function loadScripts(urls, length, success){ 
    if(length > 0){ 
     script = document.createElement("SCRIPT"); 
     script.src = urls[length-1]; 
     console.log(); 
     script.onload = function() { 
      console.log('%c Script: ' + urls[length-1] + ' loaded!', 'color: #4CAF50'); 
      loadScripts(urls, length-1, success);    
     }; 
     document.getElementsByTagName("head")[0].appendChild(script); 
    } 
    else 
     if(success) 
      success(); 
} 

Zastosowanie:

urls = ['https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js', 
    'https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js', 
    'http://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js' 
    ]; 

loadScripts(urls, urls.length, function(){ 
    /* Jquery and other codes that depends on other libraries here */ 

}); 

Ta funkcja jest mądry dla css asynchronicznie obciążenia:

function loadLinks(urls, length, success){ 
    if(length > 0){ 
     link = document.createElement("LINK"); 
     link.href = urls[length-1]; 
     link.rel = 'stylesheet'; 
     link.onload = function() { 
      console.log('%c link: ' + urls[length-1] + ' loaded!', 'color: #4CAF50'); 
      loadLinks(urls, length-1);    
     }; 
     document.getElementsByTagName("head")[0].appendChild(link); 
    } 
    else 
     if(success) 
      success(); 
} 

Sposób użycia:

links = [ 
     'https://www.amirforsati.ir/css/styles.css', 
     'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css', 
     'https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css' 
     ]; 
loadLinks(links, links.length, function(){}); 

Można używać zarówno CSS i JavaScript dla funkcji załadunku css i js asynchronicznie. użyj tych kodów w pliku, który jest ładowany asynchronicznie, jak:

<script async src="js/scripts.js"></script> 
Powiązane problemy