在其他脚本之前异步加载 jquery

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14811471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:57:08  来源:igfitidea点击:

Load jquery asynchronously before other scripts

jqueryasynchronous

提问by Fez Vrasta

I've added the asyncattrib to my javascript inclusion HTML.
So now I've:

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

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

And this works with all JS I load, all except jquery.

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

If I add asyncto jQuery <script>tag all others script who depend from jquery don't work.

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

In that jsfiddle you can see the problem:
JsFiddle

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

In the example I've used <script> Mycode </script>instead of including an external file.js, but this doesn't change the situation.

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

I'd like to run jQuery with async attrib and run other few external scripts asynchronously only after jquery is loaded.

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

It is possible?

有可能的?

采纳答案by John Zwinck

I'd like to run jQuery with async attrib and run other few external scripts asynchronously only after jquery is loaded.

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

What does that mean? It sounds a lot like you want to load jQuery first, then other things when it's done. So you want to load it synchronously. If you still want to use the asyncway, you could define an onloadfunction to continue loading other things once jQuery is ready. Or you could use defer. Both of these are explained here: https://davidwalsh.name/html5-async

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

回答by Flimm

This is a great use-case for defer:

这是一个很好的用例defer

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

Neither of these tags will block rendering. The browser can download jquery.jsand custom.jsin parallel. It will execute jquery.jsas soon as it has been downloaded and the DOM has been loaded, and custom.jswill execute afterwards.

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

Sadly, there a few issues:

可悲的是,有几个问题:

  • You can't use the deferattribute for inline scripts.
  • IE < 10 has been documented to cause scripts with deferto unexpectedly interleave their execution.
  • I can't find any specs that say that scripts with the deferorder are meant to be executed in order, just that they are meant to be executed after the DOM loads.
  • 您不能将该defer属性用于内联脚本。
  • IE <10已被记录到事业脚本与defer意外交错它们的执行
  • 我找不到任何说明带有defer订单的脚本应该按顺序执行的规范,只是它们应该在 DOM 加载后执行。

回答by ElHaix

This may be what you are looking for:
http://www.yterium.net/jQl-an-asynchronous-jQuery-Loader- jQl an asynchronous jQuery Loader.

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

It asynchronously loads jQuery without blocking other components:

它在不阻塞其他组件的情况下异步加载 jQuery:

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

jQl automatically catches all jQuery().ready()calls, so you can write:

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 will queue these function calls, and execute them as soon as jQuery is loaded and the DOM is ready, as they would be executed in the usual way.

jQl 将对这些函数调用进行排队,并在 jQuery 加载完毕且 DOM 准备就绪后立即执行它们,就像它们以通常的方式执行一样。

回答by Amir Fo

Using a recursive function

使用递归函数

I have written a function to do this job very nice.

我写了一个函数来完成这项工作,非常好。

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

});

You can put these code in a file like scripts.jsand load it with asyncattribute.

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

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

For css async load, refer to edited versions of this answer.

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

回答by ???? ????? ???? ??????

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

found it i had problems with bootstrap loads sometimes before jquery now np hope it helps others i put this script at head but gave an error cant appendChild now its before /body and checked works for all browsers i tryed script async but it didn't have an event that tell me when the download ends and some times bootstrap loaded before jquery and vise versa because bootstrap depend on jquery i had to load jquery and then start download bootstrap now i'll add fallback

发现它我有时在 jquery 之前遇到引导加载问题,现在 np 希望它可以帮助其他人我把这个脚本放在头上,但给出了一个错误 cant appendChild 现在它在 /body 之前并检查了所有浏览器的工作我尝试了脚本异步但它没有一个事件,告诉我下载何时结束,有时在 jquery 之前加载引导程序,反之亦然,因为引导程序依赖于 jquery 我必须加载 jquery,然后现在开始下载引导程序,我将添加回退

fixed it

修复

now it checks that jq loaded

and only then loads others

ok now its copy paste

现在它检查 jq 已加载

然后才加载其他人

好的现在它的复制粘贴