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 不兼容的地方。当你修复了这些不兼容问题以后,就能够安全地移除这个插件了。

相关文章
相关标签/搜索