Charger jquery de manière asynchrone avant les autres scripts

j'ai ajouté async attrib pour mon javascript intégration HTML.

Donc maintenant, j'ai:

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

et cela fonctionne avec tous les JS que je charge, tous sauf jquery.

Si j'ajoute async jQuery <script> tags tous les autres scripts qui dépendent de jquery ne fonctionnent pas.

Dans ce jsfiddle vous pouvez voir le problème:

http://jsfiddle.net/uFbdV/

Dans l'exemple que j'ai utilisé <script> Mycode </script> au lieu d'inclure un fichier externe.js, mais ça ne change pas la situation.

j'aimerais lancer jQuery avec l'atrib async et exécuter d'Autres scripts externes de façon asynchrone seulement après que jquery est chargé.

C'est possible?

33
demandé sur Fez Vrasta 2013-02-11 16:04:48

5 réponses

j'aimerais lancer jQuery avec async atrib et exécuter quelques autres les scripts sont asynchrones seulement après le chargement de jquery.

ça veut dire Quoi? On dirait que tu veux d'abord charger jQuery, puis d'autres choses quand c'est fait. Donc, vous voulez charger synchrone. Si vous voulez continuer à utiliser l' async façon, vous pouvez définir une onload fonction pour continuer à charger d'autres choses une fois que jQuery est prêt. Ou vous pourriez utilisez defer. Deux de ceux-ci sont expliqués ici: https://davidwalsh.name/html5-async

22
répondu John Zwinck 2017-11-08 13:12:09

C'est un excellent cas d'utilisation defer:

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

aucune de ces balises ne bloque le rendu. Le navigateur peut télécharger jquery.js et custom.js en parallèle. Il exécutera jquery.js dès qu'il a été téléchargé et dans les DOM a été chargé, et custom.js va exécuter par la suite.

Malheureusement, il y a quelques problèmes:

  • Vous ne pouvez pas utiliser le defer attribut pour les scripts en ligne.
  • IE < 10 a été documentée pour causer des scripts deferinattendue interleave leur exécution.
  • je ne trouve pas de specs que dire que les scripts avec l' defer commande sont destinés à être exécutés dans l'ordre, juste qu'ils sont destinés à être exécuté après le DOM.
14
répondu Flimm 2016-11-10 19:22:50

c'est peut être Ce que vous cherchez:

http://www.yterium.net/jQl-an-asynchronous-jQuery-Loader - jQl asynchrone jQuery Chargeur.

il charge de façon asynchrone jQuery sans bloquer les autres composants:

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

JQL capture automatiquement tous les jQuery().ready() appels, vous pouvez donc écrire:

<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 va mettre en file d'attente ces appels de fonction, et les exécuter dès que jQuery est chargé et que le DOM est prêt, comme ils le seraient exécuté de la manière habituelle.

13
répondu ElHaix 2016-08-12 00:46:31

à l'Aide d'une fonction récursive

j'ai écrit une fonction pour faire ce travail très agréable.

// scripts.js


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();
        }
    }
}

/* Write links sorted from last one to first to load */
/* Here, jquery will be loaded first, then materialize and then wow libray. */
urls = [ '/js/wow.js', '/js/materialize.js',  '/js/jquery.js'];

loadScripts(urls, urls.length, function(){
    /* Codes inside of here will be executed after js files load */

});

Vous pouvez mettre ces code dans un fichier scripts.js et de le charger avec async l'attribut.

<script async src="js/scripts.js"></script>

pour CSS async load, reportez-vous aux versions modifiées de cette réponse.

2
répondu Amir Forsati 2018-08-06 08:09:08
<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>

trouvé j'ai eu des problèmes avec les charges bootstrap parfois avant jquery maintenant np espère qu'il aide les autres j'ai mis ce script à la tête mais a donné une erreur cant appendChild maintenant son avant / body and checked fonctionne pour tous les navigateurs i tryed script async mais il n'a pas eu un événement qui me dire quand le téléchargement se termine et parfois bootstrap chargé avant jquery et vise versa parce que bootstrap dépendent de jquery, j'ai dû charger jquery et puis commencer à télécharger bootstrap maintenant, je vais ajouter de secours

fixe

maintenant, il vérifie que jq chargé

et alors seulement, les charges autres

ok maintenant son copier coller

-1
répondu טאבו ישראל שרות לקוחות 2017-04-16 22:38:27