【问题标题】:How to know if a JavaScript (script) was loaded?如何知道是否加载了 JavaScript(脚本)?
【发布时间】:2015-03-31 18:10:31
【问题描述】:

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

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

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

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

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

据我了解,script.readyState == "loaded" || script.readyState == "complete"仅适用于 IE,不适用于其他浏览器...

用法:

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

【问题讨论】:

  • if (isNewScript) {script.src = ...} else {callback(false);},并检查callback中传递的参数,检测脚本是否真的被加载了?
  • 这能回答你的问题吗? Verify External Script Is Loaded

标签: javascript html


【解决方案1】:

我推荐 jQuery,它非常简单。自己编写这样的东西的生命太短了(你会浪费时间来支持所有浏览器)。

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

编辑:
更简单(来自jQuery docs 的示例):

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

您还可以链接 donefail 以获得额外的回调:

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

异步加载 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>

【讨论】:

  • 这是一个更好的解决方案。
  • 谢谢。我想知道如何检查脚本是否已加载,而不是如何加载脚本,因为我不确定目前是否加载了 jQuery,所以我真的更喜欢纯 JavaScript
  • 请检查我的答案,我添加了一些代码来异步加载jquery。
【解决方案2】:

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

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

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

您还可以在 body 上触发事件并在其他父代码中侦听该事件。

【讨论】:

  • 非常方便:只需在 poper src 中添加一个脚本标签,然后在加载脚本的末尾启动一个回调。谢谢!
【解决方案3】:

基于 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,结合 Luca 和 load css using jquery 的想法:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 2020-02-12
    • 2011-05-31
    相关资源
    最近更新 更多