动态加载JavaScript文件

目录

配置

无脑方法!

逆袭之道!

一块蛋糕!

结论

源代码


JavaScript文件的动态加载是您必须拥有的非常有用的工具之一。它允许您通过将阻止脚本从加载过程中移出(通常称为延迟加载)来优化网页性能,并仅在用户需要时加载脚本(通常称为按需加载)。如果您明智地使用此工具,它将大大提高您的页面性能。

配置

让我们定义我们的示例模型,我们将从定义需要动态加载的远程文件开始。这是remote.js文件的定义:

// this is going to be executed when script is loaded
(function () {
  console.log("Remote script loaded");
}());

var sayHello = function (name) {
  alert("Hello", name);
}

在上面的代码中,我们定义了一个直接函数来跟踪文件加载。我们还定义了一个从主页面调用的自定义函数。

现在,这是我们的主要index.htm页面。它只包含一个用于加载和测试文件的按钮。

<html>
<head>
</head>
<body>
  <button id="loadButton">Load script file</button>
  <script type="text/javascript">
    document.getElementById('loadButton').onclick = function () {
      // your code goes here
    };
  </script>
</body>
</html>

无脑方法!

加载JavaScript文件最直接的方法是在<script>元素中引用它。动态加载这个文件最简单的方法就是动态加载这个元素!

让我们更新代码并查看实际结果:

document.getElementById("loadButton").onclick = function () {
  var script = document.createElement("script");
  script.src = "remote.js";

  script.onload = function () {
    sayHello("Mohammad");
  };

  // append and execute script
  document.documentElement.firstChild.appendChild(script);
};

上面的代码简单地创建了一个<script>元素并将这个元素的src字段设置为我们文件的路径。然后它使用该appendChild()函数将其附加到我们代码的第一个子<head>元素元素。以下代码产生以下结果:

现在,让我们重构上面的代码并稍微修改一下,以便能够在其他任何地方使用它:

/**
 * Used to load and execute javascript file. an be used cross-domain seamlessly.
 * @param file JS file name
 * @param callback Subscribe to get notified when script file is loaded
 **/
function require(file, callback) {
  // create script element

  var script = document.createElement("script");
  script.src = file;

  // monitor script loading
  // IE < 7, does not support onload
  if (callback) {
    script.onreadystatechange = function () {
      if (script.readyState === "loaded" || script.readyState === "complete") {
        // no need to be notified again
        script.onreadystatechange = null;
        // notify user
        callback();
      }
    };

    // other browsers
    script.onload = function () {
      callback();
    };
  }

  // append and execute script
  document.documentElement.firstChild.appendChild(script);
}

document.getElementById("loadButton").onclick = function () {
  require("remote.js", function () {
    sayHello("Mohammad");
  });
};

现在,您可以轻松调用require()以及JavaScript 路径和回调函数,以便在加载脚本时收到通知。

逆袭之道!

动态加载JavaScript文件的另一种方法是使用经典HTTP请求检索它。这是一个纯JavaScript调用,但它有很多缺点。让我们看看它的实际效果:

/**
 * Used to load and execute javascript file. Suffers from same-domain restriction.
 * @param file JS file name
 * @param callback Subscribe to get notified when script file is loaded
 **/
function requireXhr(file, callback) {
  // object initialization
  const xhr = new XMLHttpRequest();

  // subscribe to request events
  xhr.onreadystatechange = function () {
    // readyState:
    // 0 UNSENT Client has been created. open() not called yet.
    // 1 OPENED open() has been called.
    // 2 HEADERS_RECEIVED send() has been called, and headers and status are available.
    // 3 LOADING Downloading; responseText holds partial data.
    // 4 DONE The operation is complete.

    // when not done, return
    if (xhr.readyState !== 4) {
      return;
    }

    // done, check status code
    if (xhr.status !== 200) // 200 = OK
    {
      return;
    }

    // now the file is loaded,
    // go and execute the script
    eval(xhr.responseText);

    // notify caller
    if (callback) {
      callback();
    }
  };

  // open connection to file
  xhr.open("GET", file, true);

  // send the request
  xhr.send();
}

document.getElementById("loadButton").onclick = function () {
  requireXhr("remote.js", function () {
    sayHello("Mohammad");
  });
};

该代码非常简单且具有自我描述性。我们使用XMLHttpRequest对象设置一个HTML请求,然后触发它。然后,我们监控其状态变化并相应地执行。

当我们执行上面的代码时,我们得到以下结果。我们可以在DevTools扩展中看到我们成功的XHR请求:

另一方面,结果令人失望。我们能够成功运行脚本,并且HTML内容中没有脚本文件的线索,但是,由于eval()的私有范围,我们无法调用加载的函数。

这种方式的其他缺点是它在跨域工作时会受到很大影响。而且您也不能从本地路径加载!

一块蛋糕!

现在是最直接的延迟加载JavaScript文件的方式,jQuery方式。jQuery提供了一个名为getScript()(它是ajax()的简写)的函数来检索和加载JavaScript文件。这是代码:

/**
 * Used to load and execute JavaScript file. 
 * @param file JS file name
 * @param callback Subscribe to get notified when script file is loaded
 **/
 function requireAjax(file, callback) {
  jQuery.getScript(file, callback);
}

document.getElementById("loadButton").onclick = function () {
  requireAjax("remote.js", function () {
    sayHello("Mohammad");
  });
};

虽然jQuery.getScript() 在内部使用XMLHttpRequest,并且您可以在DevTools中的XHR列表中看到请求,但它没有XMLHttpRequest那样的缺点(比如同域限制)。它比原始的XMLHttpRequest更容易使用和执行。

结果也很棒:

结论

总而言之,如果您在页面中启用了jQuery,您就可以轻松地使用jQuery.getScript()按需异步加载JavaScript。如果您正在寻找一种纯JavaScript方法,请选择这种<script>方法,它产生的开销很小。

源代码

该示例可在GitHub上的以下位置获得:

https://www.codeproject.com/Articles/5310336/Dynamically-Loading-a-JavaScript-File

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值