代码改变世界

JavaScript学习之路01 - 挖掘那些被人遗忘的“介爱丝”(拾遗篇)

2013-05-14 16:16  ARMdong  阅读(178)  评论(0编辑  收藏  举报

前言:

  本人接触web开发已经小有年头了,一零年年初开始研究.net,到现在已有三年之久了。在这个过程中一直是坎坎坷坷,从当初的不知所措,到现在的确定方向,真的是很不容易。中间有过迷茫,想过放弃,但还是坚持下来了。三年,说长也不长,说短也不短,人生能有多少三年。三年里,你可以从菜鸟变成大牛,也可以从developer升迁为manager;

  好吧,感慨的话就不多说了,今天主要是想把这些年对js的学习做一个总结,写一个系列,就像博客园中的汤姆大叔那样,由于本人的功力不够,也许写不出大叔那样字字珠玑的文章,但是至少也算是总结一下自己的学习成果。这些年学习js一直是断断续续,没有真正的把它学透学精,现在借工作不是那么大压力来整理一下自己的学习,此系列文章与本人其他两个系列同步整理,主要是Linq系列和Disign Pattern系列;所以总体上来讲,进度可能没有那么快,因为没有开启多线程嘛。定的目标是年内完成所有系列的文章,希望大家能够关注,多多指出不足和交流看法。

  此系列文章主要是参考Nicholas C. Zakas著作Professional JavaScript for Web Developers, Third Edition进行的整理,大家可以在网上进行下载。如不想下载,可以联系本人索取该电子书,本人联系方式文章最后有说明。

正文:

  今天主要讲三个知识点:

  1、Deferred Scripts的介绍和使用;

  2、Asynchronous Scripts的介绍和使用;

  3、Inline code VS External files;

  太基础的东西,没必要去说也说不清的东西我不会去说,比如说为什么用<script>标签来指定js代码或者说如何在html页面中引入js代码之类的,这些都是规定好了的,不是我能说的清的,所以大家不要去探索这些问题,应该往更深层次看。。。

 

好吧,开始今天的第一个话题:Deferred Scripts

Deferred Scripts:延时执行脚本

  Html 4.0.1中为<script>元素定义了defer属性。defer的初衷是为了执行某个脚本的时候不会改变网页的结构。因此,脚本在整个页面被解析完成后才会安全的执行。

  加上defer的<script>脚本,浏览会立即去加载它但是不会马上去执行,而是等到整个页面被解析完成才去执行。(延时执行),尽管我们把<script>元素放在<head>标签中,浏览器也要等到解析完</html>的时候才会去执行defer script中的代码。例如下面给出的示例:

example.htm页面代码:

<!doctype html >
<html>
    <head>
        <title>Deferred Script </title>
        <script defer src="../js/example1.js" type="text/javascript"></script>
        <script src="../js/example2.js" type="text/javascript"></script>
    </head>
    <body>
    </body>
</html>

example1.js代码:

alert("我来自example1: " + new Date().toLocaleTimeString());

example2.js代码:

alert("我来自example2: " + new Date().toLocaleTimeString());

大家注意看html页面代码,在引入外部example1.js文件的时候,我在src属性前面添加了defer属性,而example2.js的src属性前面未做更改,我们看运行结果:主要看alert出来的时间。

我们可以看出,example1.js执行的时间比example2.js执行的时间要晚,是因为example1.js是延时执行,而example2.js会被立即解析执行的结果。

  如果<head>标签中有两个加了defer属性的<script>元素,在html5中规定了defer scripts根据他们的所放置的顺序等页面渲染完成后顺序执行,并且都会在DOMContentLoaded事件之前执行,但是实际情况中,他们并没有按规定的顺序来执行或者在DOMContentLoaded事件之前执行,所以在必要的情况下,我们最好只给一个外部引入的js文件添加defer属性;

  如上所述,defer(延时)属性只在外部引入js中被支持,所以在html5中,如果一个inline的script添加了defer属性,浏览器会自动的忽视它,因为在Html5中不支持inline方法是defer属性,只支持External的方式。

 

Asynchronous  Scripts:异步脚本

  Html5中介绍了<script>的新属性——async属性,async属性和defer相同之处就是他们改变了script在页面中的执行方式,同样,async属性只能被加在外部引入script脚本上中,并且告诉浏览器立即去加载这个外部的js文件。async属性和defer属性不同点是:async script不能保证按照指定的顺序去执行。异步异步,就是说当计算机一有空闲的时候就去解析执行,所以有很高的不确定因素。

    <script async src="../js/example1.js" type="text/javascript"></script>
    <script async src="../js/example2.js" type="text/javascript"></script>

  这段代码中,第二个script可能会比第一个script先执行,所以重点是这两个js文件之间不能有相互依赖的关系,async script的目的在于告诉浏览器去干一件事情,至于什么时候干事浏览器的事情,async并没有权利去要求、去限制浏览器必须什么时间完成。就像老板说的给你涨工资,具体什么时间涨那还是未知数,也许老板哪天高兴就给你涨了,如果老板比较抠的话,那你就慢慢等吧!好的,言归正传,正因为这种不确定因素,所以async script不能对DOM有修改结构的动作。

  Async script脚本文件一定是在页面加载完成事件Load事件触发之前先执行,至于和DOMContentLoaded谁先执行就不得而知了。FF 3.6+,Safari 5+,Chrome 7+支持async script。

 

INLINE CODE VERSUS EXTERNAL FILES

  尽管我们可以直接将JavaScript代码嵌入到html中,但是实践告诉我们将js放在一个单独的目录中更可取,虽然没有严格的要求规定我们要这样做,但是外部js文件确实有很大的益处,这里我列出主要几点:

1、可维护性

  javascript代码散布在大量的html页面中会导致维护起来非常麻烦,如果我们把js文件单独的放在一个目录下面,维护起来只要修改这个目录中的js文件即可。

2、缓存

  浏览器会通过特殊的方法将所有的外部js文件缓存在本地,也就是说如果有两个页面中都用到了同一个js文件,那么浏览器只需下载一次,从根本上解决了页面加载缓慢的问题。

3、不会过时

  通过外部引用文件的形式导入js文件,在XHTML和HTML中的语法都是一样的。而且我们没有必要担心XHTML或者hack comment的问题。

 

小结:

  Javascript脚本通过<script>元素插入到html页面中,该元素可以通过内联的方式和其他元素一起嵌入到html页面中,或者是通过外部文件引入的方式,下面是今天内容的一点总结:

  1、引入外部javascript文件时,必须设置src属性指定要引入文件的URL地址,这个外部js文件可以是和页面在同一个服务器中的文件,也可以是其他域名下的服务器中的文件,一般情况下,我们最好不要使用跨域的文件,除非这个域名的服务器是可信的。

  2、所有的<script>元素根据他们出现在页面中的位置顺序相继被执行,<script>中包含的代码必须等到上一个<script>中的代码完全解析执行完成后才能执行,除非这个<script>元素有async或者defer属性。

  3、对于所有的非defer script,浏览器会等到完全解析完这些js代码后采取渲染剩下的页面,正因为如此,通常情况下<script>元素在主要内容和</body>标签关闭之间引入。

  4、如果你希望等所有文档完全解析之后或者等整个页面渲染完成之后采取执行的话,你可以通过给<script>设置defer属性。延时执行脚本通常只是为了完成某一单独的任务,而不应该对html页面的结构造成影响。

  5、设置<script>的属性为async,我们可以不必等到前面的<script>脚本完全解析执行完成之后才去执行,而直接告诉浏览器我要干什么,告诉他你的意图。但是,异步脚本不能确定执行的时间。

  另外,如果一个浏览器不支持脚本语言的话,我们可以通过设置<noscript>元素来显示我们想要展示的东西,如果浏览器支持脚本语言的话,任何放在<noscript>中的内容都不会被渲染。

 

好的,这就是我今天要讲的所有的内容,感谢你的耐心阅读。