Ajax【转】JavaScript 的装和推行

承前面一首文章《浏览器的渲染原理简介》 ,本文来说下JavaScript的装载和履。

一般说来来说,浏览器对于 JavaScript 的周转有少数那个特点:

1) 载入后即刻行

2)
执行时会见卡住页面后续之始末(包括页面的渲染、其他资源的下载)

因而,如果发差不多个JS文件被引入,那么对于浏览器来说,这些JS文件将让串行地载入并一一执行。

由JavaScript 可能会见操作 HTML文档的DOM
树,所以浏览器一般都未会见像并行下载CSS文件一律并推行下载JS文件,这是JS文件之特殊性造成的。因此,如果你的JavaScript想操作后的DOM
元素,浏览器会报错说找不至对象,这是因JavaScript执行时后的HTML被死住了,操作DOM
树时还并未后面的节点。

 

俗方法

当您勾勒下如下代码时:

<script type="text/javascript"  src="http://coolshell.cn/asyncjs/alert.js"></script>

多来说,head里的<script>标签会阻塞后续资源的载入以及整个页面的变型。比如上面这示例,其中就发生一样句JS代码(示例):

alert(“hello world”) ;

功能是于加载此JS文件时会弹有一个会话框,因此点击是对话框后才见面对后续资源开展载入以及针对性全页面的拓转移。

用,有广大网站会把 js 放在网页的末梢对,或者使
window.load、$(document).ready(function(){}) 之类的波。

此外,由于多数的JavaScript代码并不需要等待页面,我们要异步载入功能。那我们怎么异步载入呢?

 

document.write 方式

卿恐怕当 document.write() 方式能够解决无打断的计。通过
document.write
方法勾勒副<script>标签的艺术就是得实施后的物,对于当与一个
script 标签内的
JS代码来说是这般的。但是,对于一切页面来说,还是会堵塞的。下面是同等段测试代码(示例):

<script type="text/javascript" language="javascript">
    function loadjs(script_filename) {
        document.write('<' + 'script language="javascript" type="text/javascript"');
        document.write(' src="' + script_filename + '">');
        document.write('<'+'/script'+'>');
        alert("loadjs() exit...");
    }

    var script = 'http://coolshell.cn/asyncjs/alert.js';

    loadjs(script);
    alert("loadjs() finished!");
</script>

<script type="text/javascript" language="javascript">
   alert("another block");
</script>

依此弹出的对话框为:

loadjs() exit...
loadjs() finished!
hello world
another block

下一场才见面显页面。

 

script
的defer和async属性

IE自从IE6就之处defer 标签,如:

<script defer type="text/javascript" src="./alert.js" ></script>

对IE来说,这个标签会叫IE并履行下载JS文件,并且把该执行hold到了通DOM装载完毕,多单defer
的<script>在实践时也会按部就班该冒出的各个来运转。最要之是<script>被长refer
后,其非见面堵塞后续DOM 的渲染。但是坐refer
只是IE专用,所以一般用之比少。

 

咱俩的HMTL 5也投入了一个异步载入 JavaScript的特性:async
。无论你对它们给什么样的价,只要她起,它便从头异步加载
JS文件。但是,async的异步加载会发生一个比较严重的题目,那就是是她忠实的执行“载入后旋即行”这长长的规则。所以,虽然它们并无封堵页面的渲染,但是你吗无法控制他实施之次第和机遇(示例)。

支撑 async
标签的浏览器如下,Opera还不支持(出自这里),所以这个方法吧不是太好。

Ajax 1

 

动态创建DOM的不二法门

这种方式或者是因此底绝多之了。 

function loadjs(script_filename) {
    var script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', script_filename);
    script.setAttribute('id', 'coolshell_script_id');

    script_id = document.getElementById('coolshell_script_id');
    if(script_id){
        document.getElementsByTagName('head')[0].removeChild(script_id);
    }
    document.getElementsByTagName('head')[0].appendChild(script);
}

var script = 'http://coolshell.cn/asyncjs/alert.js';
loadjs(script);

这种办法几乎变成了专业的异步载入js文件之办法(示例)。这种方法还玩出了
jsonp 的东东。也就是是咱得吧script的src
指定某个后台的台本(比如PHP),而这个PHP返回一个JavaScript函数,其参数是一个json
字符串,返回来调用我们事先定义好的 JavaScript
函数。作者的参阅示例:t.js 
(这个示例是笔者之前在微博征集的一个异步ajax调用的小例子)

 

按需要异步载入JS

上面的DOM方式的事例解决了异步载入JavaScript的题目,但是从未缓解我们怀念让他按照自指定的时运行的题目。所以,我们得拿点的DOM方式绑定到某个事件上就得了。

比如:

1) 绑在window.load
事件上(示例)

window.load = loadjs("http://coolshell.cn/asyncjs/alert.js")

2)
绑在一定的波上(示例)

<p style="cursor: pointer" onclick="LoadJS()">Click to load alert.js </p>

本当我们以点击某个DOM元素时,才载入我们的JS文件。

 

更多

有的人也许会见认为绑定在某特定事件及像过了某些,而当点击时才载入JS又极其慢了。这里废弃来一个巅峰问题:我们怀念要异步地将JS文件下充斥及用户本地,但是以非实施,仅当我们想只要实行的下才去履行。

作者提出了平等种方式,就如多年事先玩preload图片那样,我们得以 object
标签(也得使 iframe
标签),于是有了底的代码(示例):

function cachejs(script_filename){
    var cache = document.createElement('object');
    cache.data = script_filename;
    cache.id = "coolshell_script_cache_id";
    cache.width = 0;
    cache.height = 0;
    document.body.appendChild(cache);
}

以Chrome 下以F12(或者Ctrl+Shit+I),切换至 network页,可以见见 alert.js
文件已经下载了但可从不尽弹出
“hello,world”对话框的操作。然后我们再次用前“绑在一定的轩然大波及”的方式,因为浏览器端有缓存了,不会见于从服务器上下载
alert.js 文件了,这样就算会管实施进度了。

俺们还好用Ajax的主意,比如:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'new.js');
xhr.send('');

终极更领鲜独JS库,一个是ControlJS,一个叫HeadJS,专门用来开异步load
javascript文件的。

 

来源:JavaScript 的装和行

相关文章