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

时间:2015-03-31 18:10:32

标签: javascript html

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

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

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

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

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."); });

3 个答案:

答案 0 :(得分:6)

我推荐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
});

您还可以链接已完成失败以进行其他回调:

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

答案 1 :(得分:1)

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

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

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

此外,您可以在正文上触发事件并在其他父代码中侦听该事件。

答案 2 :(得分:0)

基于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。