39

我已将属性添加async到我的 javascript 包含 HTML 中。
所以现在我有:

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

这适用于我加载的所有 JS,除了 jquery。

如果我添加async到 jQuery<script>标记中,所有其他依赖于 jquery 的脚本都不起作用。

在那个 jsfiddle 你可以看到问题:
JsFiddle

在示例中,我使用<script> Mycode </script>了而不是包含外部 file.js,但这并没有改变这种情况。

我想使用 async attrib 运行 jQuery,并仅在加载 jquery 后异步运行其他几个外部脚本。

有可能的?

4

5 回答 5

24

我想使用 async attrib 运行 jQuery,并仅在加载 jquery 后异步运行其他几个外部脚本。

这意味着什么?听起来很像您想先加载 jQuery,然后在完成后加载其他内容。所以你想同步加载它。如果你仍然想使用这种async方式,你可以定义一个onload函数来在 jQuery 准备好后继续加载其他东西。或者你可以使用defer. 这两个都在这里解释:https ://davidwalsh.name/html5-async

于 2013-02-11T12:11:44.367 回答
20

这是一个很好的用例defer

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

这些标签都不会阻止渲染。浏览器可以jquery.js并行下载custom.js。它将jquery.js在下载并加载 DOM 后立即执行,然后custom.js再执行。

可悲的是,有几个问题:

  • 您不能将该defer属性用于内联脚本。
  • 已记录 IE < 10 会导致脚本意外defer交错执行
  • 我找不到任何规范说具有defer顺序的脚本应该按顺序执行,只是它们应该在 DOM 加载后执行。
于 2016-11-10T19:22:50.880 回答
15

这可能是您正在寻找的:
http ://www.yterium.net/jQl-an-asynchronous-jQuery-Loader - jQl 一个异步 jQuery 加载器。

它异步加载 jQuery 而不会阻塞其他组件:

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

jQl 自动捕获所有jQuery().ready()调用,因此您可以编写:

<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 将对这些函数调用进行排队,并在加载 jQuery 并且 DOM 准备好后立即执行它们,因为它们将以通常的方式执行。

于 2013-07-26T02:38:08.687 回答
3

使用递归函数

我写了一个函数来很好地完成这项工作。

// 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 */

});

您可以将这些代码放在一个文件中,并使用属性scripts.js加载它。async

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

对于 css 异步加载,请参阅此答案的编辑版本。

于 2017-11-14T19:04:58.733 回答
-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>

发现它我在 jquery 之前有时会遇到引导加载问题 np 希望它可以帮助其他人一个事件告诉我下载何时结束,有时在 jquery 之前加载引导程序,反之亦然,因为引导程序依赖于 jquery 我必须加载 jquery 然后开始下载引导程序现在我将添加回退

修复

现在它检查 jq 是否已加载

然后才加载其他

好的,现在它的复制粘贴

于 2017-04-16T02:05:34.093 回答