讀古今文學網 > 鋒利的jQuery(第2版) > 第10章 jQuery各個版本的變化 >

第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功能的變化,這正是本章的目的所在。