如何知道是否加载了 JavaScript(脚本)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29375510/
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-10-28 10:26:35  来源:igfitidea点击:

How to know if a JavaScript (script) was loaded?

javascripthtml

提问by serhio

I try to write a JavaScript function that loads a js script (src) and performs some callback when the script is loaded.

我尝试编写一个 JavaScript 函数来加载 js 脚本 ( src) 并在加载脚本时执行一些回调。

I also look if a script with the same srcalready exists.

我还查看是否src已经存在相同的脚本。

My problem is that if the script already loaded, the callback will not be performed. That is NOK.

我的问题是,如果脚本已经加载,则不会执行回调。那是挪威克朗。

How to know if the script was already loaded?

如何知道脚本是否已经加载?

importScript: (function (head) {

    function loadError(error) {
        throw new URIError("The script " + 
                            error.target.src + " is not accessible.");}

    return function (url, callback) {
        var existingScript = document.querySelectorAll("script[src='" + 
                             url + "']");
        var isNewScript = (existingScript.length == 0);
        var script;
        if (isNewScript) {
            script = document.createElement("script")
            script.type = "text/javascript";
        }
        else {
            script = existingScript[0];
        }
        script.onerror = loadError;
        if (script.readyState) { //IE
            script.onreadystatechange = function () {
                if (script.readyState == "loaded" || 
                    script.readyState == "complete") {
                    script.onreadystatechange = null;
                    if (callback) {
                        callback(); }
                }
            };
        } else { // others than IE
            script.onload = callback; }

        if (isNewScript) {
            script.src = url;
            head.appendChild(script); }
    }
})(document.head || document.getElementsByTagName("head")[0])

As I understand, the script.readyState == "loaded" || script.readyState == "complete"could work only for IE, not for other browsers as well...

据我了解,在script.readyState == "loaded" || script.readyState == "complete"可以工作只针对IE浏览器,而不是其他的浏览器,以及...

Usage:

用法:

importScript("myScript1.js");
importScript("myScript2.js", /* onload function: */ 
            function () { alert("The script has been OK loaded."); });

回答by Luca Steeb

I recommend jQuery, it's so easy with that. Life is too short for coding things like that yourself (you will waste hours for supporting all browsers).

我推荐jQuery,它很容易。生命太短暂,无法自己编写代码(您将浪费数小时来支持所有浏览器)。

$.ajax({
  url: "/script.js",
  dataType: "script",
  success: function() {
    console.log("script loaded");
  }
});

EDIT:
It's even easier (example from jQuery docs):

编辑:
它更容易(来自jQuery 文档的示例):

$.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) {
  console.log(data); // Data returned
  console.log(textStatus); // Success
  console.log(jqxhr.status); // 200
});

You can also chain doneand failto have additional callbacks:

您还可以链接done没有额外的回调:

$.getScript("ajax/test.js")
  .done(function(script, textStatus) {
    console.log(textStatus);
  })
  .fail(function(jqxhr, settings, exception) {
    console.log("loading script failed.");
  });

Load jQuery asynchronously

异步加载 jQuery

<script src="path/to/jquery"></script>
<script>
function wait(method) {
    if (window.$) {
        method();
    } else {
        setTimeout(function () { wait(method); }, 100); // check every 100ms
    }
}

// wait for jQuery
wait(function() {
    // jQuery has loaded!
    $("#foo").doSomething();

    // you can now load other scripts with jQuery:
    $.getScript("ajax/test.js")
      .done(function(script, textStatus) {
        console.log(textStatus);
      })
      .fail(function(jqxhr, settings, exception) {
        console.log("loading script failed.");
      });
}
</script>

回答by Vikrant Mahajan

Well the safest way to check if script is loaded is you can add a simple callback at end of script . Which if exist can be called with some data also to be passed.

那么检查脚本是否加载的最安全方法是您可以在脚本末尾添加一个简单的回调。如果存在,则可以使用一些要传递的数据来调用。

if(window.loaded){
  window.loaded(params);
}

Once the script loads it will execute this method which you can declare in your parent script which will be called.

脚本加载后,它将执行此方法,您可以在将调用的父脚本中声明该方法。

Also you can trigger an event on body and listen on that event in other parent code.

您也可以在 body 上触发一个事件并在其他父代码中监听该事件。

回答by Liang Lyon

Based on method from Luca Steeb, I refine the solution to just two script tags, for SPA applications, index.html is very compact with:

基于 Luca Steeb 的方法,我将解决方案优化为仅两个脚本标签,对于 SPA 应用程序,index.html 非常紧凑:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Simplified INDEX</title>

    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="/bootloader.js"></script>
</head>

<body>
</body>

</html>

bootloader.js, combine ideas from Luca and load css using jquery:

bootloader.js,结合 Luca 的想法并使用 jquery 加载 css

function loadScripts() {
  // jQuery has loaded!
  console.log("jquery is loaded");

  // you can now load other scripts and css files with jQuery:
  $.when($.getStylesheet('css/main.css'), $.getScript('js/main.js'))
    .then(function () {
       console.log('the css and js loaded successfully and are both ready');
    }, function () {
        console.log('an error occurred somewhere');
    });
}

function patchGetStylesheet($) {
  $.getStylesheet = function (href) {
    var $d = $.Deferred();
    var $link = $('<link/>', {
      rel: 'stylesheet',
      type: 'text/css',
      href: href
    }).appendTo('head');
    $d.resolve($link);
    return $d.promise();
  };
}

function wait(method) {
  if (window.$) {
    patchGetStylesheet(window.$);
    method();
  } else {
    setTimeout(function () {
      wait(method);
    }, 100); // check every 100ms
  }
}

// wait for jQuery
wait(loadScripts);

For bootloader.js, it could be minified、obfused.... using webpack, ...

对于 bootloader.js,它可以被缩小、混淆……使用 webpack,……

We will not add code to index.html any more through solving runtime dependency using jquery.

我们将不再通过使用 jquery 解决运行时依赖来向 index.html 添加代码。