[翻譯]High Performance JavaScript(003)

Dynamic Script Elements  動態腳本元素

 

    The Document Object Model (DOM) allows you to dynamically create almost any part of an HTML document using JavaScript. At its root, the <script> element isn't any different than any other element on a page: references can be retrieved through the DOM, and they can be moved, removed from the document, and even created. A new <script> element can be created very easily using standard DOM methods:

    文檔對象模型(DOM)允許你使用JavaScript動態創建HTML的幾乎全部文檔內容。其根本在於,<script>元素與頁面其他元素沒有什麼不同:引用變量可以通過DOM進行檢索,可以從文檔中移動、刪除,也可以被創建。一個新的<script>元素可以非常容易地通過標準DOM函數創建:
var script = document.createElement_x("script");
script.type = "text/javascript";
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);

    This new <script> element loads the source file file1.js. The file begins downloading as soon as the element is added to the page. The important thing about this technique is that the file is downloaded and executed without blocking other page processes, regardless of where the download is initiated. You can even place this code in the <head> of a document without affecting the rest of the page (aside from the one HTTP connection that is used to download the file).

    新的<script>元素加載file1.js源文件。此文件當元素添加到頁面之後立刻開始下載。此技術的重點在於:無論在何處啓動下載,文件的下載和運行都不會阻塞其他頁面處理過程。你甚至可以將這些代碼放在<head>部分而不會對其餘部分的頁面代碼造成影響(除了用於下載文件的HTTP連接)。
    When a file is downloaded using a dynamic script node, the retrieved code is typically executed immediately (except in Firefox and Opera, which will wait until any previous dynamic script nodes have executed). This works well when the script is self-executing but can be problematic if the code contains only interfaces to be used by other scripts on the page. In that case, you need to track when the code has been fully downloaded and is ready for use. This is accomplished using events that are fired by the dynamic <script> node.

    當文件使用動態腳本節點下載時,返回的代碼通常立即執行(除了Firefox和Opera,他們將等待此前的所有動態腳本節點執行完畢)。當腳本是“自運行”類型時這一機制運行正常,但是如果腳本只包含供頁面其他腳本調用調用的接口,則會帶來問題。這種情況下,你需要跟蹤腳本下載完成並準備妥善的情況。可以使用動態<script>節點發出事件得到相關信息。
    Firefox, Opera, Chrome, and Safari 3+ all fire a load event when the src of a <script> element has been retrieved. You can therefore be notified when the script is ready by listening for this event:

    Firefox, Opera, Chorme和Safari 3+會在<script>節點接收完成之後發出一個load事件。你可以監聽這一事件,以得到腳本準備好的通知:

var script = document.createElement_x("script")
script.type = "text/javascript";
//Firefox, Opera, Chrome, Safari 3+
script.onload = function(){
  alert("Script loaded!");
};
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);

    Internet Explorer supports an alternate implementation that fires a readystatechange event. There is a readyState property on the <script> element that is changed at various times during the download of an external file. There are five possible values for readyState:

    Internet Explorer支持另一種實現方式,它發出一個readystatechange事件。<script>元素有一個readyState屬性,它的值隨着下載外部文件的過程而改變。readyState有五種取值:

"uninitialized" The default state

uninitialized”默認狀態
"loading" Download has begun

loading”下載開始
"loaded" Download has completed

loaded”下載完成
"interactive" Data is completely downloaded but isn't fully available

interactive”下載完成但尚不可用
"complete" All data is ready to be used

complete”所有數據已經準備好
    Microsoft's documentation for readyState and each of the possible values seems to indicate that not all states will be used during the lifetime of the <script> element, but there is no indication as to which will always be used. In practice, the two states of most interest are "loaded" and "complete". Internet Explorer is inconsistent with which of these two readyState values indicates the final state, as sometimes the <script> element will reach the "loaded" state but never reach "complete" whereas other times "complete" will be reached without "loaded" ever having been used. The safest way to use the readystatechange event is to check for both of these states and remove the event handler when either one occurs (to ensure the event isn't handled twice):

    微軟文檔上說,在<script>元素的生命週期中,readyState的這些取值不一定全部出現,但並沒有指出哪些取值總會被用到。實踐中,我們最感興趣的是“loaded”和“complete”狀態。Internet Explorer對這兩個readyState值所表示的最終狀態並不一致,有時<script>元素會得到“loader”卻從不出現“complete”,但另外一些情況下出現“complete”而用不到“loaded”。最安全的辦法就是在readystatechange事件中檢查這兩種狀態,並且當其中一種狀態出現時,刪除readystatechange事件句柄(保證事件不會被處理兩次):
var script = document.createElement_x("script")
script.type = "text/javascript";
//Internet Explorer
script.onreadystatechange = function(){
  if (script.readyState == "loaded" || script.readyState == "complete"){
    script.onreadystatechange = null;
    alert("Script loaded.");
  }
};
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);

    In most cases, you'll want to use a single approach to dynamically load JavaScript files. The following function encapsulates both the standard and IE-specific functionality:

    大多數情況下,你希望調用一個函數就可以實現JavaScript文件的動態加載。下面的函數封裝了標準實現和IE實現所需的功能:

function loadScript(url, callback){
  var script = document.createElement_x("script")
  script.type = "text/javascript";
  if (script.readyState){ //IE
    script.onreadystatechange = function(){
      if (script.readyState == "loaded" || script.readyState == "complete"){
        script.onreadystatechange = null;
        callback();
      }
    };
  } else { //Others
    script.onload = function(){
      callback();
    };
  }
  script.src = url;
  document.getElementsByTagName("head")[0].appendChild(script);
}

    This function accepts two arguments: the URL of the JavaScript file to retrieve and a callback function to execute when the JavaScript has been fully loaded. Feature detection is used to determine which event handler should monitor the script's progress. The last step is to assign the src property and add the <script> element to the page. The loadScript() function is used as follows:

    此函數接收兩個參數:JavaScript文件的URL,和一個當JavaScript接收完成時觸發的回調函數。屬性檢查用於決定監視哪種事件。最後一步,設置src屬性,並將<script>元素添加至頁面。此loadScript()函數使用方法如下:
loadScript("file1.js", function(){
  alert("File is loaded!");
});

    You can dynamically load as many JavaScript files as necessary on a page, but make sure you consider the order in which files must be loaded. Of all the major browsers, only Firefox and Opera guarantee that the order of script execution will remain the same as you specify. Other browsers will download and execute the various code files in the order in which they are returned from the server. You can guarantee the order by chaining the downloads together, such as:

    你可以在頁面中動態加載很多JavaScript文件,但要注意,瀏覽器不保證文件加載的順序。所有主流瀏覽器之中,只有Firefox和Opera保證腳本按照你指定的順序執行。其他瀏覽器將按照服務器返回它們的次序下載並運行不同的代碼文件。你可以將下載操作串聯在一起以保證他們的次序,如下:
loadScript("file1.js", function(){
  loadScript("file2.js", function(){
    loadScript("file3.js", function(){
      alert("All files are loaded!");
    });
  });
});

    This code waits to begin loading file2.js until file1.js is available and also waits to download file3.js until file2.js is available. Though possible, this approach can get a little bit difficult to manage if there are multiple files to download and execute.

    此代碼等待file1.js可用之後纔開始加載file2.js,等file2.js可用之後纔開始加載file3.js。雖然此方法可行,但如果要下載和執行的文件很多,還是有些麻煩。
    If the order of multiple files is important, the preferred approach is to concatenate the files into a single file where each part is in the correct order. That single file can then be downloaded to retrieve all of the code at once (since this is happening asynchronously, there's no penalty for having a larger file).

    如果多個文件的次序十分重要,更好的辦法是將這些文件按照正確的次序連接成一個文件。獨立文件可以一次性下載所有代碼(由於這是異步進行的,使用一個大文件並沒有什麼損失)。
    Dynamic script loading is the most frequently used pattern for nonblocking JavaScript downloads due to its cross-browser compatibility and ease of use.

    動態腳本加載是非阻塞JavaScript下載中最常用的模式,因爲它可以跨瀏覽器,而且簡單易用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章