jQuery 3 有哪些新東西

https://github.com/cssmagic/blog/issues/59 @Aurelio De Rosa

css

jQuery 的橫空出世,至今已有十個年頭了,而它的長盛不衰顯然不是沒有理由的。jQuery 提供了極爲友好的接口,使得開發者們能夠方便地進行 DOM 操做、發起 Ajax 請求、生成動畫……不一而足。此外,與 DOM API 不一樣的是,jQuery 採用了 「混合模式」。這意味着你能夠在任何一個 jQuery 集合身上調用 jQuery 方法,而不用關心它到底包含了幾個元素(無論是零個、一個或多個,都沒問題)。在將來的幾周內,jQuery 就將抵達一個重要的里程碑——正式發佈 3.0 版本。jQuery 3 修復了大量的 bug,增長了新的方法,同時移除了一些接口,並修改了少許接口的行爲。在這篇文章中,我將爲你們重點講解 jQuery 3 所引入的那些最重要的變化。 jquery

 

新增特性git

 

咱們先來討論 jQuery 3 中最重要的幾個新增特性。github

 

for...of 循環ajax

 

在 jQuery 3 中,咱們能夠用 for...of 循環語句來迭代一個 jQuery 集合中的全部 DOM 元素。這種新的迭代方法是 ECMAScript 2015(即 ES6)規範中的一部分。這個方法能夠對 「可迭代對象」(好比 Array、Map、Set 等)進行循環。npm

 

當使用這種新的迭代方法時,你在循環體內每次拿到的值並非一個 jQuery 對象,而是一個 DOM 元素(譯註:這一點跟 .each() 方法相似)。當你在對一個 jQuery 集合進行操做時,這個新的迭代方法能夠少量改善你的代碼。瀏覽器

 

爲了搞清楚這種迭代方法究竟是怎麼工做的,咱們來假設一個場景——你須要給頁面中的每一個 input 元素分配一個 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++;

}

 

(譯註:其實 jQuery 本身是有個 .each() 方法的,可讀性也不賴。)

 

$.get() 和 $.post() 函數的新簽名

 

jQuery 3 爲 $.get() 和 $.post() 這兩個工具函數增長了新簽名,從而使得它們和 $.ajax() 的接口風格保持一致。新簽名是這樣的:

 

$.get([settings])

 

$.post([settings])

 

settings 是一個對象,它包含多個屬性。它的格式和你之前傳給 $.ajax() 的參數格式是同樣的。若是你想更清楚地瞭解這個參數對象,請參考 $.ajax() 頁面 中的相關描述。

 

$.get() 和 $.post() 的參數對象與傳給 $.ajax() 的參數相比,惟一的區別就是前者的 method 屬性老是會被忽略。緣由其實也很簡單,$.get() 和 $.post() 自己就已經預設了發起 Ajax 請求的 HTTP 方法了(顯然 $.get() 就是 GET,而 $.post() 就是 POST)。也就是說,正常人類應該是不會想用 $.get() 方法來發送一個 POST 請求的。

 

假設有如下一段代碼:

 

$.get({

    url: 'https://www.audero.it',

    method: 'POST' // This property is ignored

                   // 這個屬性將被忽略

});

 

無論咱們把 method 屬性寫成什麼,這個請求老是會以 GET 的方式發出去的。

 

採用 requestAnimationFrame() 來實現動畫

 

全部現代瀏覽器(包括 IE10 及以上)都是支持 requestAnimationFrame 的。jQuery 3 將會在內部採用這個 API 來實現動畫,以便達到更流暢、更省資源的動畫效果。

 

unwrap() 方法

 

jQuery 3 爲 unwrap() 方法增長了一個可選的 selector 參數。這個方法的新簽名是這樣的:

 

unwrap([selector])

 

有了這個特性,你就能夠給這個方法傳入一個包含選擇符表達式的字符串,用它來在父元素內進行匹配。若是存在匹配的子元素,則這個子元素的父層將被解除;若是沒有匹配,則不進行操做。

 

有變動的特性

 

jQuery 3 還修改了一些特性的行爲。

 

:visible 和 :hidden

 

jQuery 3 將會修改 :visible 和 :hidden 過濾器的含義。只要元素具備任何佈局盒,哪怕寬高爲零,也會被認爲是 :visible。舉個例子,br 元素和不包含內容的行內元素如今都會被 :visible 這個過濾器選中。

 

所以,若是你的頁面中包含以下的結構:

 

<div><div>

<br />

 

而後運行如下語句:

 

console.log($('body :visible').length);

 

在 jQuery 1.x 和 2.x 中,你獲得的結果會是 0;但在 jQuery 3 中,你會獲得 2。

 

data() 方法

 

另外一個重要的變化是跟 data() 方法有關的。如今它的行爲已經變得跟 Dataset API 規範 一致了。jQuery 3 將會把全部屬性鍵名轉換成駝峯形式。咱們來詳細看一下,以以下元素爲例:

 

<div id="container"><div>

 

當咱們在用 jQuery 3 之前的版本時,若是運行以下代碼:

 

var $elem = $('#container');

 

$elem.data({

   'my-property': 'hello'

});

 

console.log($elem.data());

 

將會在控制檯獲得以下結果:

 

{my-property: "hello"}

 

而在 jQuery 3 中,咱們將會獲得以下結果:

 

{myProperty: "hello"}

 

請注意,在 jQuery 3 中,屬性名已經變成了駝峯形式,橫槓已經被去除了;而在之前的版本中,屬性名會保持全小寫,並原樣保留橫槓。

 

Deferred 對象

 

jQuery 3 還改變了 Deferred 對象的行爲。Deferred 對象能夠說是 Promise 對象的前身之一,它實現了對 Promise/A+ 協議 的兼容。這個對象以及它的歷史都至關有意思。若是想要深刻了解,你能夠去閱讀 jQuery 官方文檔,也能夠去看我寫的書《jQuery 實戰(第三版)》——這本書也涵蓋了 jQuery 3。

 

在 jQuery 1.x 和 2.x 中,傳給 Deferred 的回調函數內若是出現未捕獲的異常,會當即中斷程序的執行(譯註:即靜默失敗,其實 jQuery 絕大多數回調函數的行爲都是這樣的)。而原生的 Promise 對象並不是如此,它會拋出異常,並不斷向上冒泡,直至到達 window.onerror(一般冒泡的終點是這裏)。若是你沒有定義一個函數來處理這個錯誤事件的話(一般咱們都不會這麼作),那這個異常的信息將會被顯示出來,此時程序的執行纔會中止。

 

jQuery 3 將會遵循原生 Promise 對象的模式。所以,回調內產生的異常將會致使失敗狀態(rejection),並觸發失敗回調。一旦失敗回調執行完畢,整個進程就將繼續推動,後續的成功回調將被執行。

 

爲了讓你更好地理解這個差別,讓咱們來看一個小例子。好比咱們有以下代碼:

 

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 中,只有第一個函數(也就是拋出錯誤的那個函數)會被執行到。此外,因爲咱們沒有爲 window.onerror 定義任何事件處理函數,控制檯將會輸出 「Uncaught Error: An error」,並且程序的執行將停止。

 

而在 jQuery 3 中,整個行爲是徹底不一樣的。你將在控制檯中看到 「Failure 1」 和 「Success 2」 兩條消息。那個異常將會被第一個失敗回調處理,而且,一旦異常獲得處理,那麼後續的成功回調將被調用。

 

SVG 文檔

 

沒有哪個 jQuery 版本(包括 jQuery 3)曾官方宣稱支持 SVG 文檔。不過事實上有不少方法是能夠奏效的,此外還有一些方法在之前是不行的(好比操做類名的那些方法),但它們在 jQuery 3 中也獲得了更新。所以,在 jQuery 3 中,你應該能夠放心使用諸如 addClass() 和 hasClass() 這樣的方法來操做 SVG 文檔了。

 

已廢棄、已移除的方法和屬性

 

在增長了上述改進的同時,jQuery 也移除、廢棄了一些特性。

 

廢棄 bind()、unbind()、delegate() 和 undelegate() 方法

 

jQuery 在好久之前就引入了 on() 方法,它提供了一個統一的接口,用以取代 bind()、delegate() 和 live() 等方法。與此同時,jQuery 還引入了 off() 這個方法來取代 unbind()、undelegated() 和 die() 等方法。從那時起,bind()、delegate()、unbind() 和 undelegate() 就已經再也不推薦使用了,但它們仍是一直存在着。

 

jQuery 3 終於開始將這些方法標記爲 「廢棄」 了,並計劃在將來的某個版本(極可能是 jQuery 4)中將它們完全移除。所以,請在你的項目中統一使用 on() 和 off() 方法,這樣你就不用擔憂將來版本的變動了。

 

移除 load()、unload() 和 error() 方法

 

jQuery 3 完全拋棄了 load()、unload() 和 error() 等已經標記爲廢棄的方法。這些方法在很早之前(從 jQuery 1.8 開始)就已經被標記爲廢棄了,但一直沒有去掉。若是你正在使用的某款插件仍然依賴這些方法,那麼升級到 jQuery 3 會把你的代碼搞掛。所以,在升級過程當中請務必留意。

 

移除 context、support 和 selector 屬性

 

jQuery 3 完全拋棄了 context、support 和 selector 等已經標記爲廢棄的屬性。同上,在升級到 jQuery 3 時,請留意你正使用的插件。

 

已修復的 Bug

 

jQuery 3 修復了以往版本中的一些很是重要的 bug。在本節中,我將着重介紹其中兩處,由於這二者應該會對你寫代碼的習慣帶來顯著影響。

 

width() 和 height() 的返回值將再也不取整

 

jQuery 3 修復了 width()、height() 和其它相關方法的一個 bug。這些方法的返回值將再也不捨入取整,由於這種取整行爲在某些狀況下不便於對元素進行定位。

 

咱們來詳細看一看。假設你一個寬度爲 100px 的容器元素,它包含了三個子元素,寬度均爲三分之一(即 33.333333%):

 

<div class="container">

   <div>My name<div>

   <div>is<div>

   <div>Aurelio De Rosa<div>

<div>

 

在 jQuery 3 之前的版本中,若是你嘗試經過如下代碼來獲取子元素的寬度……

 

$('.container div').width();

 

……那麼你獲得結果將是 33。緣由在於 jQuery 會把 33.33333 這個值取整。而在 jQuery 3 中,這個 bug 已經被修復了,所以你將會獲得更加精確的結果(即一個浮點數)。

 

wrapAll() 方法

 

jQuery 3 還修復了 wrapAll() 方法中的一個 bug,這個 bug 出如今把一個函數做爲參數傳給它的狀況下。在 jQuery 3 之前的版本中,當一個函數被傳給 wrapAll() 方法時,它會把 jQuery 集合中的每一個元素單獨包裹起來。換句話說,這種行爲和把一個函數傳給 wrap() 時的行爲是徹底同樣的。

 

在修復這個問題的同時,還引入了另一個變動:因爲在 jQuery 3 中,這個函數只會調用一次了,那就沒法把 jQuery 集合中每一個元素都傳給它。所以,這個函數的執行上下文(this)將只能指向當前 jQuery 集合中的第一個元素。

 

如何下載 jQuery 3 beta 1

 

既然你已經讀到了這裏,那說明你極可能想試試 jQuery 3 的第一個 beta 測試版。你能夠經過如下兩個地址來獲取這個版本:

 

  • 未壓縮版: 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

 

結論

 

不少人一直在唱衰 jQuery,說它在現代網頁開發中已經沒有一席之地了。但無論怎樣,jQuery 的開發仍在繼續,客觀的統計數據(在排名前一百萬名的網站中佔有率高達 78.5%)也讓這些論調不攻自破。

 

在本文中,我已經帶你瞭解了一遍 jQuery 3 將會帶來的一些重大變化。或許你已經察覺到了,這個版本並不太可能搞掛你的既有項目,由於它引入的破壞性變動其實寥寥無幾。不過,在升級到 jQuery 3 的過程當中,你仍是有必要牢記一些關鍵點,好比 Deferred 對象的改進等等。一樣,在升級某個第三方庫時,也有必要檢查一下該項目的兼容性狀況,以便儘早發現任何非預期行爲,避免某些功能失效。

 

譯註

 

除了本文所說起的變動以外,jQuery 3.0 最大的變化就是完全放棄對 IE8 的支持。jQuery 團隊作出這個決定的緣由在於,微軟已經在今年年初宣佈中止對 IE 8~10 的支持。所以,jQuery 在 3.0 alpha 階段所發佈的 jQuery Compat 項目也就沒有繼續存在的必要了。

 

不過,因爲 IE8 仍然是中國大陸最流行的瀏覽器之一,對國內的開發者來講,在短時間(甚至中期)內還不得不停留在 jQuery 1.x 版本。

 

好吧,最後仍是說個好消息吧。爲幫助用戶平滑升級,這次 jQuery 一樣會爲 3.0 版本提供遷移插件(jQuery Migrate plugin)。在把 jQuery 升級到 3.0 以後同時運行這個插件,便可確保基於 jQuery 1.x 或 2.x 的既有業務代碼正常運行;同時,它還將在控制檯向你報告既有代碼與 jQuery 3 不兼容的地方。當你修復了這些不兼容問題以後,就能夠安全地移除這個插件了。

相關文章
相關標籤/搜索