jQuery 3.0 beta 發布
創作不夠,譯文來湊。
跟上篇一樣是編譯,不準備逐字翻。比如,我會把“we”譯成“jQuery官方團隊”,或者“他們”。
初譯版,待校正。這篇文章比較長,翻譯難度也不小,如果有問題,歡迎提出,我盡量修改。
正文開始。
歪果仁也要雙喜臨門,于是 jQuery 官方團隊選在 jQuery 面世10周年之際發布 3.0 beta。大家還記得上周發布的1.x和2.x小版本更新吧,他們日后會繼續維護這倆分支,一段時間,當然只改bug。因為3.0才是未來嘛!
需要支持IE6-8的可憐蟲請繼續使用1.12分支上的最新版。
沒有兼容版了
看過 alpha 發布公告的同學可能還記得,他們起初準備同時發布3.0和“3.0兼容版”,適配老瀏覽器。但是現在他們想通了。微軟今年1月12日宣布放棄IE8910,jQuery 會保守一些,不過至少不打算支持IE8,所以就放棄所謂的兼容版,以后就只有一個版本了。
盡管大版本號發生變化,jQuery 團隊仍然認為升級不會太麻煩。大變化是有,不過影響應該沒有很大,而且他們還開發了3.0專用遷移插件,可以幫助我們找到代碼中的兼容性問題。所以,請盡早使用新版本,并及時將體驗反饋給他們,這樣才能讓jQuery 越來越好。
你可以直接通過CDN使用:
https://code.jquery.com/jquery-3.0.0-beta1.js
https://code.jquery.com/jquery-3.0.0-beta1.min.js
或者用NPM安裝到本地
npm install jquery@3.0.0-beta1
重點變化
接下來就是需要關注的新功能、升級、以及 Bug 修正了。完整列表見于 Github。
.show()和.hide()
剛啟動3.0的時候,他們嘗試將這兩個方法修改為“刪除行內display:none樣式”(.show())和 “增加行內display:none樣式”(.hide())。這樣可以極大的簡化實現所需的代碼,并且顯著改善性能(計算量大幅下降了嘛)。但是,這給廣大用戶帶來了不小的麻煩,因為移除display:none很多時候并不能讓元素顯示出來,比如有其它CSS將它置為隱藏。最終 jQuery 團隊不得不承認沒有辦法完成期望中的簡化。
于是他們放棄了這次嘗試。不過,即便如此,他們還是想辦法改善了隱藏大量元素時的性能。
.data()的注意事項
為了兼容 HTML5 dataset 規范,jQuery 團隊升級了.data()實現。如今所有的 key 都會從短線連接(a-bc-de)轉換成駝峰式(aBcDe),數字不再轉換。于是,“foo-bar”轉換后和“fooBar”是一樣的,但“foo-42”和“foo42”就不一樣。當用戶直接使用.data()取所有數據時,就需要注意這個區別,尤其不要再誤用.data('foo42')取代.data('foo-42')。
jQuery.Deferred 現在兼容 Promises/A+
Promise 我用的比較少,看到的文檔也不多,不太清楚里面的幾個名詞怎么翻譯,所以我盡量用括號備注。
jQuery.Deferred 得到升級,兼容 Promises/A+ 和 ES2015 Promises,并且已經通過 Promises/A+ Compliance Test Suite 認證。這意味著.then()的使用機制發生了非常顯著的變動:
-
.then()回調函數里拋出的異常,會成為失敗(rejection)處理函數的參數。之前,異常會冒泡,中斷函數執行,并永久性鎖死上下級 Deferred 對象。
-
由.then()返回的 Deferred 對象,如果它的回調函數拋出異常,將會調用失敗(rejection)處理函數,并作為參數傳進去;如果返回其它不能繼續.then()的對象,就會調用成功(fulfillment)處理函數,返回值也作為參數傳進去。以前,失敗處理函數返回任何值都會將其置為失敗。
-
回調函數將固定為異步執行。以前它們在綁定或者解決時會被立即執行。
-
進度的回調函數不會再把它綁定的 Deferred 對象標記為完成。
以下代碼演示當上級 Deferred 觸發rejected時,下級調用失敗回調函數之后的結果:
var parent = jQuery.Deferred(); var child = parent.then( null, function() { return "bar"; }); var callback = function( state ) { return function( value ) { console.log( state, value ); throw new Error( "baz" ); }; }; var grandchildren = [ child.then( callback( "fulfilled" ), callback( "rejected" ) ), child.then( callback( "fulfilled" ), callback( "rejected" ) ) ]; parent.reject( "foo" ); console.log( "parent resolved" );
在 jQuery 3.0 中,會先輸出“parent resolved”,然后再執行回調函數;然后下級 Deferred 進入失敗狀態,執行函數,返回“bar”;“bar”被轉化為三級 Deferred 的成功,于是輸出“fulfilled bar”;接著,拋出錯誤“baz”,導致三級函數進入錯誤處理;最后,輸出“rejected baz”。如果是之前的版本,下級 Deferred 會認為上級 Deferred 失敗,進入錯誤處理,輸出“rejected bar”;并且在未捕獲的錯誤“baz”被拋出后,整個進程立刻被終止;此時,由于三級函數未處理完,“parent resolved”也不會輸出。
捕獲異常不僅對在瀏覽器里調試有幫助,在失敗后的回調函數中處理它們,也使得代碼更加直觀合理。請謹記,這也意味著使用 Promise 模式的時候,要至少設置一個函數處理失敗。不然的話,所有錯誤都會被忽略掉。
如果你還想使用以前的代碼,可以用.pipe()函數替換.then()。后者雖然已經被標記為不建議使用,但它接口一樣,而且會暫時延續之前的邏輯。
我們還開發了輔助調試調試 Promises/A+ 的工具。如果你覺得有些錯誤好像沒觸發出來,可以試用之。
jQuery.when函數也升級了,現在可以傳入任何支持.then()的對象,包括原生 Promise 對象。
https://github.com/jquery/jquery/issues/1722
https://github.com/jquery/jquery/issues/2102
Deferreds 對象增加.catch()方法
Promise 對象增加.catch()方法, 作為.then(null, fn)的別名,專門處理失敗。
移除jQuery.ajax的 Deferred 同名方法的特殊用法
jqXHR是 Promise 對象,同時也有一些專有方法,比如.abort(),用于取消請求。
現在,越來越多的開發者已經在異步中(如AJAX)使用 Promise 模式,如此一來,jQuery.ajax返回的對象再包含特殊用法就不合時宜了。
success, error, complete(這些將被移除)
done, fail, always(這些應該會保留)
需要注意的是,那些繼續存在的回調函數不會有任何變化,只有 Promise 的方法會受影響。
錯誤不再被悄無聲息地消失
有時候我們難免會想:“window 的偏移值(window.offset)是多少?”等你回過味兒來你會發現這個問題其實挺蠢的,window 怎么會有偏移呢?
過去,jQuery 面對這種情況,從來不會拋出錯誤,而是盡量返回有意義的值,比如剛才那個問題,就返回{ top: 0, left: 0 }。3.0之后,他們嘗試不再什么亂七八糟的代碼都兼容,而是直接拋出錯誤,讓用戶不要忽略這些問題。大家可以試用 beta 版,看看你的代碼有沒有“參數無效”之類的錯誤。
.width(),.height(),.css('width'),.css('height')都將返回小數
之前,jQuery 取寬高的時候會返回四舍五入之后的整數值。有些瀏覽器可以返回次像素,比如 IE 和 Firefox,有些用戶需要這些精細的數據來調整布局。jQuery 官方團隊認為這項變化對大多數人沒有影響,不過如果你受此困擾,也請告知他們。
移除廢棄的事件別名
jQuery 1.8之后棄用的.load,.unload,.error方法被正式移除。以后都請使用.on()注冊事件偵聽器。
使用requestAnimationFrame改善動畫效果
新版 jQuery 在支持requestAnimationFrame的平臺上會自動使用它來改善性能。除去 IE9 和 低于4.4的Android,都可以藉此讓動畫效果更平滑,占用更少的CPU時間,降低移動設備的電力損耗。
其實 jQuery 團隊幾年前就曾嘗試使用這項技術,但是當時遇到很嚴重的兼容性問題,以致于不得不放棄。如今他們采用新策略,當瀏覽器 tab 不顯示時掛起動畫,這樣就可以規避大部分問題。不過這樣一來,那些必須依賴動畫全局實時播放的功能就無法實現了。
.unwrap( selector )
3.0之前,.unwrap()方法不接受任何參數。如今,用戶可以通過傳入選擇器來移除指定的外部容器。
jQuery.fn.domManip不能再使用了
1.12 和 2.2 版本把jQuery.dir,jQuery.sibling,jQuery.buildFragment,jQuery.access,和jQuery.swap都修改為私有函數。現在,jQuery.fn.domManip也一樣。它們未來都只允許內部使用,不會被載入使用文檔。官方團隊認為這樣做可以避免用戶困惑。
https://github.com/jquery/jquery/pull/2182
https://github.com/jquery/jquery/issues/2224
https://github.com/jquery/jquery/issues/2225
jQuery 自定義選擇器提速
拜 Paul Irish 在 Google 的工作所賜,新版 jQuery 可以躲過一些坑,比如前文提到的:visible,通過減少冗余代碼,獲得了17倍的速度提升!
但用戶仍需小心,即便經過優化,:visible和:hidden選擇器仍然會消耗大量的系統資源,因為它們需要瀏覽器檢查元素是否顯示在頁面上。在最壞的情況下,有可能需要重新計算全部 CSS 樣式和頁面布局!當然也不是說不要用(不然還寫它做甚),只是記得測試一下,看有沒有因此導致性能問題。
這項工作他們 1.12/2.2 時就完成了,只不過拿到這里來說。
我的博客:jQuery 3.0 beta 發布
來自: http://segmentfault.com/a/1190000004317448