首页 » 锋利的jQuery(第2版) » 锋利的jQuery(第2版)全文在线阅读

《锋利的jQuery(第2版)》第10章 jQuery各个版本的变化

关灯直达底部

10.1 jQuery的发展历史

2005年8月,John Resig提议改进Prototype的“Behaviour”库,于是他在blog上发表了自己

的想法,并用了3个例子做说明。

第一个例子是为元素注册一个事件:

他认为应该改写为:

第二个例子是为不同的元素注册不同的事件:

他认为应该改写为:

第三个例子是为不断变化的元素注册不同的事件:

他认为应该改写为:

这些代码也是jQuery语法的最初雏形。当时John的想法很简单:他发现这种语法相对现有的JavaScript库更为简洁。但他没想到的是,这篇文章一经发布就引起了业界的广泛关注。于是John开始认真思考着这件事情(编写语法更为简洁的JavaScript程序库),直到2006年1月14日,John正式宣布以jQuery的名称发布自己的程序库。随之而来的是jQuery的快速发展。

2006年8月,jQuery的第一个稳定版本,并且已经支持CSS选择符、事件处理和AJAX交互。

2007年7月,jQuery 1.1.3版发布,这次小版本的变化包含了对jQuery选择符引擎执行速度的显著提升。从这个版本开始,jQuery的性能达到了Prototype、Mootools以及Dojo等同类JavaScript库的水平。同年9月,jQuery 1.2版发布,它去掉了对XPath选择符的支持,原因是相对于CSS语法它已经变得多余了。这一版能够对效果进行更为灵活的定制,而且借助新增的命名空间事件,也使插件开发变得更容易。同时,jQuery UI项目也开始启动,这个新的套件是作为曾经流行但已过时的Interface插件的替代项目而发布的。jQuery UI中包含大量预定义好的部件(widget),以及一组用于构建高级元素(例如可拖放、拖拽、排序)的工具。

注意:XPath(XML Path Language, XML路径语言)是在XML文档中识别不同元素或者元素值的一种语言,与CSS在HTML文档中识别元素的方式类似。在涉及属性选择符时,jQuery使用了XPath中的惯例来标识属性,即将属性前置一个@符号并放在一对方括号中。例如,要选择所有带title属性的链接,可以使用下面的代码:

但在jQuery 1.2去掉对XPath选择符的支持后,这种写法就不能用了,必须使用如下代码:

在一些老的代码和插件中这种问题比较常见。

2008年5月,jQuery 1.2.6版发布,这版主要是将Brandon Aaron开发的流行的Dimensions

插件的功能移植到了核心库中,同时也修改了许多BUG,而且有不少的性能得到提高。因此,如果把你以前的jQuery版本升级到1.2.6,那么你完全可以从你的代码中排除Dimensions插件。

注意:Dimensions插件是一个获得元素尺寸、定位的插件。

在jQuery迅速发展的同时,一些大的厂商也看中了商机。2009年9月,微软和诺基亚公司正式宣布支持开源的jQuery库,另外,微软公司还宣称他们将把jQuery作为Visual Studio工具集的一部分。他将提供包括jQuery的智能提示、代码片段、示例文档编制等内容在内的功能。微软和诺基亚公司将长期成为jQuery的用户成员,其他成员还有Google, Intel, IBM, Intuit等公司。

2009年1月,jQuery 1.3版发布,它使用了全新的选择符引擎Sizzle,在各个浏览器下全面超越其他同类型JavaScript框架的查询速度,程序库的性能也因此有了极大提升。这一版本的第2个变化就是提供live方法,使用live方法可以为当前及将来增加的元素绑定事件,在1.3版之前,如果要为将来增加的元素绑定事件,需要使用livequery插件,而在1.3版中,可以直接用live方法。

注意:Sizzle是jQuery作者John Resig新写的DOM选择器引擎。Sizzle有一个重要的特点,它是完全独立于jQuery的,如果你不想用jQuery,可以只用Sizzle。Sizzle下载地址:http://sizzlejs.com/

2010年1月,也是jQuery的四周年生日,jQuery 1.4版发布,为了庆祝jQuery四周岁生日,jQuery团队特别创建了jquery14.com站点,带来了连续14天的新版本专题介绍。

在1.3及更早版本中,jQuery通过JavaScript的eval方法来解析json对象。在1.4中,如果你

用的浏览器支持,则会使用原生的JSON.parse解析json对象,这样对json对象的书写验证则更为严格。比如:{foo: “bar”}的写法将不会被验证为合法的json对象,必须写成{“foo”:”bar”}。如果你的程序打算升级到1.4版本,那么这一点要尤其注意。

2010年2月,jQuery 1.4.2版发布,它新增了有关事件委托的两个方法:delegate和undelegate。delegate用于替代1.3.2中的live方法。这个方法比live来的方便,而且也可以达到动态添加事件的作用。比如给表格的每个td绑定hover事件,代码如下:

2011年1月,jQuery 1.5版发布。该版本做了如下修改:

 重写Ajax模块

(1)最大的变化是调用jQuery.ajax(或jQuery.get, jQuery.post等)会返回jqXHR的对象,

为不同浏览器内置的XMLHttpRequest对象提供了一致的超集,可以完成以前不可能完成的任务,比如:中止JSONP请求。

(2)提供了更高级的统一的API。

(3)更好的扩展性,可以方便地扩展Ajax的发送与接收,管理Ajax请求。

 新增延迟对象

开发人员借此可以使用无法立即获得的返回值(如异步Ajax请求的返回结果),而且第一次能够附加多个事件处理器。

比如,使用新的jQuery Ajax API实现下面的代码:

 jQuery.sub

可以方便地创建jQuery副本,不影响原有的jQuery对象,避免jQuery冲突。示例代码如下:

 内部开发系统

jQuery团队内部开发系统的两点改变:一是服务器端用NodeJS替换了老的Java/Rhino系统,使得团队可以专注于JavaScript环境的新变化;二是所用的代码压缩优化程序从Google Closure Compiler切换到UglifyJS,新工具的压缩效果非常令人满意。

2011年5月,jQuery 1.6版发布。该版本重写了Attribute模块和大量的性能改进。值得注意的是此次更新有2个破坏性的变更,将会影响到现有打算升级到1.6的那些项目。

 变更1:更新data方法

在jQuery1.5中,data方法可以用来将元素上的数据属性转化为JSON形式的值。JQuery 1.6已经更新了此功能,data方法获取的值会以驼峰形式展示,以配合W3C HTML5规范。比如:

 变更2:独立方法处理DOM属性,以区分DOM的attributes和properties

一般情况下,attributes表示从文档中获取DOM的状态信息,而properties表示元素的动态状态信息。比如:

如果用户手动改变文本框的值为“abcdef”,那么:

同样,如果网页中的复选框的代码如下:

那么结果也会有所不同:

所以在jQuery 1.6中,如果要判断复选框是否选中,需在事件处理程序中使用:

由于jQuery 1.6对attr方法的改变,导致很多使用attr方法的程序出现问题,必须修改为1.6的语法才能使用,这个不向前兼容的改变引起了开发的强烈不满。于是在不到10天的时间里,jQuery 1.6.1发布,它调整了attr方法,使其兼容1.6之前的做法。比如:

2011年11月,jQuery 1.7版发布。该版本做了如下修改:

 新的事件API: on和off

新的on和offAPI统一了jQuery中所有对文档绑定事件的操作,而且它们也更加简短。代码如下:

其中on替代了之前版本中的bind、delegate和live; off替代了unbind、undelegate和die。下面代码是新旧API调用之间对应的例子:

 事件委托的性能改进

随着页面大小和复杂度的不断增长,事件委托变得越来越重要。比如Backbone, JavaScript MVC和Sproutcore等应用框架都使用了大量的事件委托。考虑到这一点,jQuery 1.7重构了事件委派,使其更加快速,尤其是在大多数常见情况下。图10-1是1.6.4和1.7版本的性能比较,最终的事件委托和1.6.4相比,节省了大约一半的时间:

图10-1 不同版本的性能比较

 更好地支持IE 6/7/8下的HTML 5

任何试图在IE 6/7/8中使用新的类似于<section>的HTML 5标签,毫无疑问都会遇到IE 6/7/8无法解析这些标签,甚至将这些标签从文档中移除的问题。在jQuery 1.7中,为较旧IE版本中html一类的方法建立了对HTML 5的支持。这一功能和以前的innerShiv相同,但你仍然需要在你的文档头部加入HTML5Shiv(或者Modernizr)以使旧IE版本支持HTML 5标签。如需要更多资料,请查看The Story of the HTML5 Shiv(http://paulirish.com/2011/the-history-of-the-html5-shiv/)。

 更直观地切换动画

在jQuery的旧版本中,类似于slideToggle或fadeToggle的切换动画在互相堆放和前一个动

画被stop终止时无法正常工作。在1.7版本中这一情况被修复,动画系统会记住元素的初始值并在一个切换的动画被提前终止时重置它们。

 异步模块定义(AMD)

jQuery 1.7支持AMD规范,可以和遵循AMD规范的脚本加载器协作,比如RequireJS或者curl.js。

 jQuery.Deferred

jQuery.Deferred对象除了提供新的进度处理及通知方法之外,同时也新增一个可用来取得目前Deferred状态的state方法。Deferred也通过jQuery.Callbacks机制来提供给开发者一个统一的事件处理接口。

 jQuery.isNumeric

在使用jQuery的过程中,有时候需要知道一个参数是数值或可以被成功的转换为数值的情况。所以jQuery开发并公开jQuery.isNumeric方法。为它传递一个任意类型的参数,它将对应的返回true或false。

 弃用和删除的功能

jQuery将开始弃用过时的特性,以使代码库更加精简,同时提高性能。比如live和die已在1.7版本中被弃用,这些方法还将继续有效,但为了兼容以后的版本不建议使用它们,可以使用on、off和delegate之类的代替。

一些非标准的特性在1.7版本中被彻底移除了,比如event.layerX和event.layerY,可以使用event.originalEvent.layerX和event.originalEvent.layerY代替。

jQuery.isNaN:这一未公开的实用函数已被删除,新的jQuery.isNumeric提供了类似的功能,并且可以被更好的支持。

jQuery.event.proxy:这一未公开和过时的方法已被删除,开发者应使用公开的jQuery.proxy方法代替。

jQuery所有版本的发行说明可以在官方站点查到,网址为http://blog.jquery.com/和http://jquery.org/history/。

10.2 jQuery各个版本新增方法

jQuery各版本新增方法如表10-1~表10-5所示。

表10-1 jQuery 1.3新增方法

方法名称说 明返回值.closest从元素本身开始,逐级向上级元素匹配,并返回最先匹配的 祖先元素jQuery.context返回传给jQuery的原始的DOM节点内容:如果没有获得通 过,那么上下文将可能是该文档Element.die从元素中删除先前用.live绑定的所有事件jQuery.live附加一个事件处理器到符合目前选择器的所有元素匹配,元素 可以是现在和未来的元素jQueryjQuery.queue显示在匹配的元素上的已经执行的函数列队ArrayjQuery.dequeue在匹配的元素上执行队列中的下一个函数jQueryjQuery.fx.off关闭页面上所有的动画BooleanjQuery.isArray确定参数是否是一个数组BooleanjQuery.support一组用于展示不同浏览器各自特性和bug的属性集合Objectevent.currentTarget在事件冒泡阶段中的当前DOM元素Elementevent.isDefaultPrevented根据事件对象中是否调用过event.preventDefault方法来返回 一个布尔值Booleanevent.isImmediatePropagationStopped根据事件对象中是否调用过event.stopImmediatePropagation 方法来返回一个布尔值Booleanevent.isPropagationStopped根据事件对象中是否调用过event.stopPropagation方法来返 回一个布尔值Booleanevent.result这个属性包含了当前事件最后触发的那个处理函数的返回值, 除非值是undefinedObjectevent.stopImmediatePropagation阻止剩余的事件处理函数执行并且防止事件冒泡到DOM树上undefined

表10-2 jQuery 1.4新增方法

方法名称说 明返回值jQuery.error(message)接受一个字符串,并抛出包含这个字符串的异常jQuery.toArray返回jQuery集合中所有元素Array.first获取元素集合中第一个元素jQuery.last获取元素集合中最后一个元素jQuery.has(selector)保留包含特定后代的元素,去掉那些不含有指定后代的元素jQueryjQuery.contains(container, contained)一个DOM节点是否包含另一个DOM节点Boolean.prevUntil([selector])获取每个当前元素之前所有的同辈元素,直到遇到选择器匹 配的元素为止,但不包括选择器匹配的元素jQuery.nextUntil([selector])获取每个当前元素之后所有的同辈元素,直到遇到选择器匹 配的元素为止,但不包括选择器匹配的元素jQuery.parentsUntil([selector])查找当前元素的所有的父辈元素,直到遇到选择器匹配的元素 为止,但不包括那个匹配到的元素jQuery.unwrap将匹配元素的父级元素删除,保留自身(和兄弟元素,如果 存在)在原来的位置。和.wrap的功能相反jQuery.detach([selector])从DOM中去掉所有匹配的元素。.detachh和.remove一样, 除了.detach保存所有jQuery数据和被移走的元素相关联。当 需要移走一个元素,不久又将该元素插入DOM时,这种方法 很有用jQuery.delegate(selector, eventType, handler)为所有选择器匹配的元素附加一个处理一个或多个事件,现在 或将来,基于一组特定的根元素jQuery.undelegate为所有选择器匹配的元素删除一个处理一个或多个事件,现在 或将来,基于一组特定的根元素jQuery.focusin(handler(eventObject))将一个事件函数绑定到“focusin”事件。focusin事件会在元素 (或者其内部的任何元素)获得焦点时触发。这跟focus事件 的显著区别在于,它可以在父元素上检测子元素获得焦点的情 况(换而言之,它支持事件冒泡)这个函数是.bind('focusin', handler)的快捷方式。jQuery.focusout(handler(eventObject)将一个事件函数绑定到“focusout”事件。focusout事件会在元素 (或者其内部的任何元素)失去焦点时触发。这跟blur事件的 显著区别在于,它可以在父元素上检测子元素失去焦点的情况 (换而言之,它支持事件冒泡)。这个方法是.bind('focusout', handler)的快捷方式jQueryevent.namespace当事件被触发时此属性包含指定的命名空间String.delay(duration, [queueName])设置一个延时来推迟执行队列中之后的项目jQueryjQuery.fx.interval该动画的频率(以毫秒为单位)NumberjQuery.noop当你仅仅想要传递一个空函数的时候,就用他吧。这对一些 插件很有用,当插件提供了一个可选的回调函数接口,那么 如果调用的时候没有传递这个回调函数,就用jQuery.noop 来代替执行FunctionjQuery.proxy(function, context)接受一个函数,然后返回一个新函数,并且这个新函数始终保 持了特定的上下文语境FunctionjQuery.parseJSON(json)接受一个标准格式的JSON字符串,并返回解析后的 JavaScript对象Object.clearQueue([queueName])从列队中移除所有未执行的项jQueryjQuery.type(obj)确定JavaScript对象的类型StringjQuery.isEmptyObject(object)检查对象是否为空(不包含任何属性)BooleanjQuery.isPlainObject(object)测试对象是否是纯粹的对象(通过“{}”或者“new Object”创建的)BooleanjQuery.isWindow(obj)确定参数是否为一个窗口(window对象)BooleanjQuery.now返回一个数字代表当前时间new Date.getTimeNumberfadeToggle([duration], [easing], [callback])通过透明度动画来显示或隐藏匹配的元素jQueryjQuery.cssHooks扩展其他的css属性。cssHooks是jQuery用来实现跨浏览器 CSS特效的手法Object

表10-3 jQuery 1.5新增方法

方法名称说 明返回值deferred.done(doneCallbacks)添加处理程序被调用时,延迟对象得到解决Deferreddeferred.fail(failCallbacks)添加处理程序被调用时,延迟对象将被拒绝Deferreddeferred.isRejected确定延迟对象是否已被拒绝Booleandeferred.isResolved确定延迟对象是否已得到解决Booleandeferred.promise返回延迟对象的Promise对象,用来观察当某种类型的所有行动绑 定到集合,排队与否还是已经完成。Deferreddeferred.reject(args)拒绝延迟对象,并根据给定的参数调用任何失败的回调函数Deferreddeferred.rejectWith(context, [args])拒绝延迟对象,并根据给定的上下文和参数调用任何失败的回调函数Deferreddeferred.resolve(args)解决延迟对象,并根据给定的参数调用任何完成的回调函数Deferreddeferred.resolveWith(context, args)解决延迟对象,并根据给定的上下文和参数调用任何完成的回调函数Deferreddeferred.then(doneCallbacks, failCallbacks)添加处理程序被调用时,延迟对象得到解决或者拒绝DeferredjQuery.hasData(element)判断一个元素是否有与之相关的任何jQuery数据BooleanjQuery.parseXML(data)把字符串转化为xml文档XMLDocumentjQuery.sub可创建一个新的jQuery副本,不影响原有的jQuery对象jQueryiQuery.when(deferreds)提供一种方法来执行一个或多个对象的回调函数,延迟对象通常 表不异步事件PromisejQuery.ajaxPrefilter([dataTypes], handler(options, originalOptions, jqXHR))在请求发送之前,绑定和修改ajax参数。相当于一个前置过滤器undefined

表10-4 jQuery 1.6新增方法

方法名称说 明返回值deferred.always(alwaysCallbacks)当延迟对象是解决或拒绝时被调用添加处理程序Deferreddeferred.pipe([doneFilter], [failFilter])筛选器和/或链Deferreds的实用程序方法Promise:focus选择当前获取焦点的元素jQueryjQuery.holdReady(hold)暂停或恢复.ready事件的执行Boolean.promise([type], [target])返回一个Promise对象用来观察当某种类型的所有行动绑定到集 合,排队与否还是已经完成Promise.prop(propertyName)获取在匹配的元素集中的第一个元素的属性值String.removeProp(propertyName, value)为匹配的元素删除设置的属性jQuery

表10-5 jQuery 1.7新增方法

方法名称说 明返回值jQuery.Callbacks(flags)一个多用途的回调列表对象,提供了强大的的方式来管理回调函数列表undefinedcallbacks.add(callbacks)回调列表中添加一个回调或回调的集合undefinedcallbacks.disable禁用回调列表中的回调undefinedcallbacks.empty从列表中删除所有的回调undefinedcallbacks.fire(arguments)用给定的参数调用所有的回调undefinedcallbacks.fired确定如果回调至少已经调用一次Booleancallbacks.fireWith([context] [,args])访问给定的上下文和参数列表中的所有回调undefinedcallbacks.has(callback)确定是否提供的回调列表Booleancallbacks.lock锁定在其当前状态的回调列表undefinedcallbacks.locked确定是否已被锁定的回调列表Booleancallbacks.remove(callbacks)删除回调或回调回调列表的集合undefineddeferred.notify(args)调用一个给定args的延迟对象上的进行中的回调progressCallbacksDeferreddeferred.notifyWith(context [, args])根据给定的上下文和args的延迟对象上回调progressCallbacksDeferreddeferred.piogress(progressCallbacks)当延迟对象生成进度通知时,添加的处理程序被调用Deferreddeferred.state确定一个延迟对象的当前状态Stringevent.delegateTarget当前jQuery事件处理程序附加的元素ElementjQuery.isNumeric(value)确定参数是否是一个数字Boolean.off(events[, selector] [, handler])移除用.on绑定的事件处理程序jQuery.on(events[, selector] [,data], handler)在选择元素上绑定一个或多个事件的事件处理函数jQuery

10.3 小结

本章主要对jQuery的发展历史和jQuery各个版本新增方法进行讲解。jQuery的不断升级完善的同时也为开发者带来不少困扰,特别是一些方法的改变而导致的不兼容。所以,对于开发者来说,最好的方式就是掌握每个版本jQuery功能的变化,这正是本章的目的所在。