[翻译]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下载中最常用的模式,因为它可以跨浏览器,而且简单易用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值