翻譯自: http://developer.telerik.com/featured/whats-new-in-jquery-3/
從jQuery 震撼整個(gè) Web ,至今已有十年了,我們有很好的理由一直堅(jiān)持使用維護(hù)它。jQuery為用戶提供了 DOM 進(jìn)行操作,執(zhí)行 Ajax 請(qǐng)求,創(chuàng)建動(dòng)畫等等,極為友好的接口。此外,與 DOM API 不同的是,jQuery 采用了 復(fù)合模式(composite pattern) 。 正因?yàn)槿绱耍憧梢栽谝粋€(gè)jQuery集合上調(diào)用jQuery方法,而不用擔(dān)心集合包含的元素?cái)?shù)量(零,一個(gè)或多個(gè))。
在未來的幾周內(nèi),隨著 jQuery 3 的發(fā)布,jQuery 會(huì)到達(dá)一個(gè)重要的里程碑。jQuery 3 修復(fù)了很多 bug,增加了新的方法,棄用并移除了一些功能,并改變了一些功能的行為。在這篇文章中,我重點(diǎn)講解jQuery 3所帶來的一些最大的變化。
新特性(New Features)
在下面的章節(jié)中,我將討論jQuery 3中新增的重要特性。
for…of 循環(huán)
jQuery 3 將提供
for...of
循環(huán)語句,可以用來遍歷一個(gè)jQuery集合所有的 DOM 元素。這種新的迭代器ECMAScript 2015(又名的ECMAScript6)規(guī)范的一部分。它能實(shí)現(xiàn)對(duì)可遍歷對(duì)象(包括
Array
、
Map
、
Set
等)的循環(huán)。
當(dāng)使用這個(gè)新的迭代方法時(shí),您每次接收的值不是一個(gè)jQuery集合,而是一個(gè)DOM元素。當(dāng)你對(duì)一個(gè)jQuery集合執(zhí)行操作時(shí),這個(gè)新的迭代方法可以少許改善你的代碼。
為了理解這個(gè)迭代方法是如何工作的,假設(shè)你想給頁面中每個(gè)
input
元素分配一個(gè) ID。在 jQuery 3 之前,你可以這樣寫:
var $inputs = $('input'); for(var i = 0; i < $inputs.length; i++) { $inputs[i].id = 'input-' + i; }
而在 jQuery 3 中,你可以這樣寫:
var $inputs = $('input'); var i = 0; for(var input of $inputs) { input.id = 'input-' + i++; }
$.get() 和 $.post()的新簽名
jQuery 3 為
$.get()
和
$.post()
工具函數(shù)增加了新簽名,為的是使得它們和
$.ajax()
的接口風(fēng)格保持一致。新簽名是這樣的:
$.get([settings]) $.post([settings])
settings
是一個(gè)可以具有許多屬性的對(duì)象。這是對(duì)象和 提供給
$.ajax()
的對(duì)象 是相同的。更多詳細(xì)的介紹,詳細(xì)介紹,請(qǐng)參考
$.ajax()
頁面
。
傳遞給
$.get()
和
$.post()
?的對(duì)象,跟傳遞給 $.ajax() 的對(duì)象相比,唯一的區(qū)別是前者?
method
屬性總是會(huì)被忽略。其原因是,
$.get()
和
$.post()
?都有一個(gè)預(yù)設(shè)的HTTP方法來執(zhí)行Ajax請(qǐng)求(?
$.get()
用 GET,而
$.post()
用 POST)。一般說來,你不要用
$.get()
嘗試發(fā)送 POST 請(qǐng)求。
考慮下面這段代碼:
$.get({ url: 'https://www.audero.it', method: 'POST' // This property is ignored });
盡管設(shè)置了
method
屬性,該語句還是不能發(fā)送 POST 請(qǐng)求,而只能發(fā)送 GET 請(qǐng)求。
采用 requestAnimationFrame() 來實(shí)現(xiàn)動(dòng)畫
所有現(xiàn)代瀏覽器,包括Internet Explorer10及以上版本,都支持 requestAnimationFrame 。jQuery 3 將會(huì)在內(nèi)部采用這個(gè) API 來實(shí)現(xiàn)動(dòng)畫,以便達(dá)到更流暢、更省CPU資源的動(dòng)畫效果。
unwrap()
jQuery 3 為
unwrap()
方法增加了一個(gè)可選的選擇器參數(shù)。這個(gè)方法的新簽名為:
unwrap([selector])
有了這一變化,你就可以傳入包含一個(gè)選擇器表達(dá)式的字符串,在父元素內(nèi)進(jìn)行匹配。如果存在匹配,匹配的子元素將被解包;否則,不進(jìn)行任何操作。
被變更的特性
jQuery 3 還修改了一些特性的行為。
:visible?和 :hidden
jQuery 3修改了
:visible
與
:hidden
過濾器的含義。只要元素具有任何布局盒,包括那些寬度和/或高度為0的情況,則元素被認(rèn)為是
:visible
。比如說,
br
元素和沒有內(nèi)容的內(nèi)聯(lián)元素進(jìn)可以通過
:visible
過濾器進(jìn)行選擇。
所以,假如頁面有如下標(biāo)記:
<div></div> <br />
然后執(zhí)行下面的語句:
console.log($('body :visible').length);
在 jQuery 1.x 和 2.x 中,你得到的結(jié)果會(huì)是
0
;但在 jQuery 3 中,你會(huì)得到
2
。
data()
另一個(gè)重要變化是跟
data()
方法的行為有關(guān)。調(diào)整主要是為了讓該方法符合
Dataset API 規(guī)范
。jQuery 3 將所有屬性的鍵都改為駝峰式大小寫形式。要理解這個(gè)變化,先看下面這個(gè)例子。
<div id="container"></div>
如果你使用 jQuery 3 之前的版本,你可以寫如下代碼:
var $elem = $('#container'); $elem.data({ 'my-property': 'hello' }); console.log($elem.data());
您將在控制臺(tái)上獲得如下結(jié)果:
{my-property: "hello"}
而在jQuery 3 中,你會(huì)獲得如下結(jié)果:
{myProperty: "hello"}
請(qǐng)注意,在 jQuery 3 中,屬性名已經(jīng)變成了駝峰形式,沒有橫杠(連字符);而在以前的版本中,屬性名會(huì)保持全小寫,并原樣保留橫杠(連字符)。
Deferred 對(duì)象
jQuery 3改變了
Deferred
對(duì)象的行為,
Promise
對(duì)象的前身,改善與
Promise/A+ 提案
的兼容性。這個(gè)
對(duì)象及其歷史非常有意思,你可以讀讀
官方文檔
,或者看看我的書
《jQuery 實(shí)戰(zhàn),第 3 版》
,這本書也涵蓋了 jQuery 3
。
在 jQuery 1.x 和 2.x 中,傳入
Deferred
中的回調(diào)函數(shù)中如果出現(xiàn)未捕獲異常,會(huì)導(dǎo)致程序停止執(zhí)行。而原生的
Promise
對(duì)象并非如此,它會(huì)拋出異常,并不斷向上冒泡,直至到達(dá)
window.onerror
(通常)。如果你沒有定義一個(gè)函數(shù)來處理這個(gè)錯(cuò)誤事件的話(通常我們都不會(huì)這么做),則會(huì)顯示異常消息,程序終止執(zhí)行。
jQuery 3 會(huì)遵循原生的
Promise
對(duì)象的模式。因此,拋出的異常將被視為一個(gè)失敗狀態(tài)(rejection),從而執(zhí)行失敗回調(diào)。完成之后,整個(gè)進(jìn)程就繼續(xù)執(zhí)行,后續(xù)的成功回調(diào)將被執(zhí)行。
為了讓你更好地理解這個(gè)差異,讓我們來看一個(gè)小例子。考慮下面的代碼:
var deferred = $.Deferred(); deferred .then(function() { throw new Error('An error'); }) .then( function() { console.log('Success 1'); }, function() { console.log('Failure 1'); } ) .then( function() { console.log('Success 2'); }, function() { console.log('Failure 2'); } ); deferred.resolve();
在 jQuery 1.x 和 2.x 中,只執(zhí)行第一個(gè)函數(shù)(拋出錯(cuò)誤的函數(shù))會(huì)被執(zhí)行到。此外,由于我們沒有為
window.onerror
定義任何事件處理函數(shù),所以控制臺(tái)將輸出消息:“Uncaught Error: An error”,而且程序的執(zhí)行將中止。
而在 jQuery 3 中,行為則完全不同的。你將在控制臺(tái)中看到 “Failure 1” 和 “Success 2” 兩條消息。異常將會(huì)被第一個(gè)失敗回調(diào)處理,一旦被處理,則繼續(xù)執(zhí)行下面的成功函數(shù)。
?
SVG 文檔
沒有哪一個(gè) jQuery 版本,包括 jQuery 3,正式支持 SVG 文檔。不過事實(shí)上有很多方法是可以正常工作的,另外一些方法,比如操作類名的方法,已經(jīng)在 jQuery 3 中進(jìn)行了更新,因此也適用。因此,在未來的版本中,你應(yīng)該可以放心使用諸如
addClass()
和
hasClass()
這樣的方法來操作 SVG 文檔了。
已廢棄、已移除的方法和屬性
除了前面說的改進(jìn),jQuery 也移除、廢棄了一些特性。
廢棄
BIND()
,
UNBIND()
,
DELEGATE()
和
UNDELEGATE()
jQuery 以前引入的
on()
方法提供了統(tǒng)一的訪問接口,取代 ?
bind()
、
delegate()
以及
live()
方法。與此同時(shí),jQuery 用
off()
方法來取代
unbind()
、
undelegated()
及
die()
方法。
bind()
、
delegate()
、
unbind()
和
undelegate()
今后不建議使用,但是并沒有采取進(jìn)一步的行動(dòng)。
jQuery 3 已經(jīng)廢棄這些方法,并計(jì)劃在未來的版本(可能是 jQuery 4)中移除它們,要堅(jiān)持在項(xiàng)目中使用
on()
和
off()
方法,這樣你就不用擔(dān)心未來版本的變更了。
移除 load(), unload() 和 error()方法
jQuery 3 徹底拋棄了已經(jīng)廢棄的?
load()
、
unload()
和
error()
?方法。這些方法在很早以前(從 jQuery 1.8 開始)就已經(jīng)被標(biāo)記為廢棄了,但仍一直存在。如果你正在使用的插件仍然依賴這些方法,那么升級(jí)到 jQuery 3 的時(shí)候,代碼就會(huì)出錯(cuò)。因此,在升級(jí)過程中要注意。
移除?context, support 和 selector
jQuery 3 徹底拋棄了已經(jīng)廢棄的?
context
、
support
和
selector
?屬性。如前所述,如果項(xiàng)目中仍然使用著這些屬性,或者某個(gè)插件仍在依賴這些屬性,那么更新到 jQuery 3 時(shí),代碼就會(huì)出錯(cuò)。
Bugs 修復(fù)
jQuery 3 修復(fù)了以前版本中的一些重大 Bug。在下面的章節(jié)中,我將著重介紹其中兩處,因?yàn)檫@兩處會(huì)對(duì)你的編碼產(chǎn)生重大影響
width() 和?height()的返回值不再四舍五入
jQuery 3 修復(fù)了
width()
、
height()
和其它相關(guān)方法中的一個(gè) bug。這些方法的返回值將不再四舍五入取整到像素了,因?yàn)椋@使得在某些情況下很難,對(duì)元素進(jìn)行定位。
要理解這個(gè)問題,讓我們假設(shè)你有一個(gè)具有100像素的寬度的容器元素,這個(gè)元素有寬度均為三分之一(即 33.333333%)的3個(gè)子元素:
<div class="container"> <div>My name</div> <div>is</div> <div>Aurelio De Rosa</div> </div>
在 jQuery 3 以前的版本中,如果你嘗試通過以下代碼來獲取子元素的寬度……
$('.container div').width();
……那么你得到結(jié)果將是
33
。原因在于 jQuery 會(huì)將 33.33333 這個(gè)值四舍五入取整。而在 jQuery 3 中,這個(gè) Bug 已經(jīng)得到修復(fù),你的結(jié)果會(huì)更精確(比如會(huì)得到浮點(diǎn)數(shù))。
wrapAll()
jQuery的新版本中還修復(fù)?
wrapAll()
?方法的一個(gè)bug,這個(gè)bug會(huì)在傳遞一個(gè)函數(shù)給?
wrapAll()
?方法時(shí)發(fā)生。在 jQuery 3 以前的版本中,當(dāng)一個(gè)函數(shù)被傳給
wrapAll()
方法時(shí),它會(huì)把 jQuery 集合中的每個(gè)元素單獨(dú)包裹起來。換句話說,這種行為和把一個(gè)函數(shù)傳給
wrap()
時(shí)的行為是完全一樣的。
除了修復(fù)這個(gè)問題,因?yàn)檫@種函數(shù)在 jQuery 3 中只會(huì)被調(diào)用一次,所以jQuery 集合元素的索引不可能被傳入。最后,該函數(shù)上下文(
this
)將指向 jQuery 集合中的第一個(gè)元素。
下載 jQuery 3 beta 1
如果此文讓你產(chǎn)生了興趣,你可以試試 jQuery 3 的第一個(gè) beta 版 。通過下面兩個(gè) URL 都可以下載到它。
- 未壓縮版本: https://code.jquery.com/jquery-3.0.0-beta1.js
- 壓縮版本: https://code.jquery.com/jquery-3.0.0-beta1.min.js
它也可在npm,通過運(yùn)行以下命令下載它:
npm install jquery@3.0.0-beta1
總結(jié)
很多人在說jQuery 已死,認(rèn)為在現(xiàn)代網(wǎng)頁開發(fā)中已經(jīng)沒有一席之地了。然而,jQuery 的開發(fā)仍在繼續(xù), 客觀的統(tǒng)計(jì)數(shù)據(jù)(在排名前一百萬名的網(wǎng)站中占有率高達(dá) 78.5%) 駁斥這些說法。
在本文中,我已經(jīng)帶你了解了一遍 jQuery 3 將會(huì)帶來的一些重大變化。或許你已經(jīng)注意到了,這個(gè)版本是可能對(duì)你現(xiàn)有的項(xiàng)目產(chǎn)生太大的影響,因?yàn)闆]有引入太多許多重大更改。盡管如此,仍然需要注意一些因素,比如
Deferred
對(duì)象的改進(jìn)。就像更新第三方依賴所經(jīng)常要面的那樣,對(duì)項(xiàng)目一定要做一個(gè)復(fù)查,從而防止意外行為或功能崩潰的情況出現(xiàn)。
?