App下載

教你如何動態(tài)加載 JavaScript 文件 詳細(xì)代碼實(shí)例解析

流年絮語 2021-09-10 10:52:35 瀏覽數(shù) (3623)
反饋

JavaScript 文件的動態(tài)加載是你必須擁有的非常有用的工具之一。它允許你通過將阻塞腳本從加載過程中移出(通常稱為“延遲加載”)來優(yōu)化網(wǎng)頁性能,并僅在用戶需要時(shí)加載腳本(通常稱為“按需加載”)。如果您明智地使用此工具,它將大大提高你的頁面性能。

配置

讓我們定義我們的示例模型,我們將從定義需要?jiǎng)討B(tài)加載的遠(yuǎn)程文件開始。這是“ ?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);
}

在上面的代碼中,我們定義了一個(gè)立即函數(shù)來跟蹤文件加載。我們還定義了一個(gè)從主頁面調(diào)用的自定義函數(shù)。

現(xiàn)在,這是我們的主要“ ?index.htm? ”頁面。它只包含一個(gè)用于加載和測試文件的按鈕。

<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>?元素中引用它。動態(tài)加載這個(gè)文件最簡單的方法就是動態(tài)加載這個(gè)元素?。銢]有看到即將到來嗎?是嗎?)

讓我們更新代碼并查看實(shí)際結(jié)果:

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

上面的代碼簡單地創(chuàng)建了一個(gè)?<script>?元素并將?src?這個(gè)元素的字段設(shè)置為我們文件的路徑。然后它使用該?appendChild()?函數(shù)將其附加到我們代碼的第一個(gè)子?<head>?元素元素。以下代碼產(chǎn)生以下結(jié)果:

Image 1

現(xiàn)在,讓我們重構(gòu)上面的代碼并稍微修改一下,以便能夠在其他任何地方使用它:

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

現(xiàn)在,你可以輕松調(diào)用require()JavaScript 路徑和回調(diào)函數(shù),以便在加載腳本時(shí)收到通知。

費(fèi)力方法

動態(tài)加載 JavaScript 文件的另一種方法是使用經(jīng)典 HTTP 請求檢索它。這是一個(gè)純 JavaScript 調(diào)用,但它有很多缺點(diǎn)。讓我們看看它的實(shí)際效果:

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

該代碼非常簡單且具有自我描述性。我們使用?XMLHttpRequestobject?設(shè)置一個(gè) HTML 請求,然后觸發(fā)它。然后,我們監(jiān)控其狀態(tài)變化并相應(yīng)地執(zhí)行。

當(dāng)我們執(zhí)行上面的代碼時(shí),我們得到以下結(jié)果。我們可以在 DevTools 擴(kuò)展中看到我們成功的 XHR 請求:

Image 2

另一方面,結(jié)果令人失望。我們能夠成功運(yùn)行腳本,并且 HTML 內(nèi)容中沒有腳本文件的線索,但是,由于?eval()?的私有范圍,我們無法調(diào)用加載的函數(shù)。

Image 3

這種方式的其他缺點(diǎn)是它在跨域工作時(shí)會受到很大影響。而且你也不能從本地路徑加載!

簡單方法

現(xiàn)在是最直接的延遲加載 JavaScript 文件的方式,jQuery 方式。jQuery 提供了一個(gè)名為?getScript()?(它是?ajax()?的簡寫)的函數(shù)來檢索和加載 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");
  });
};

雖然在內(nèi)部?jQuery.getScript() ?使用?XMLHttpRequest?,并且您可以在 DevTools 中的 XHR 列表中看到請求,但它不會遭受與?XMLHttpRequest?. 它比 ?raw ?更容易使用和執(zhí)行?XMLHttpRequest?。

Image 4

結(jié)果也很棒:

Image 5

結(jié)論

總而言之,如果你在頁面中啟用了 jQuery,你就可以輕松地??jQuery.getScript(?)?按需異步加載 JavaScript。如果你正在尋找一種純 JavaScript 方法,請選擇這種?<script>?方法,它產(chǎn)生的開銷很小。


0 人點(diǎn)贊