jQuery 3 中的新变动

Paste_Image.png

译者:李鑫

原文:What’s New in jQuery 3

本文为极客学院Wiki组织翻译,转载请注明出处。

时间:2016.3.11

十年前 jQuery 的出现震撼了整个 Web 开发,如今它的一些优秀特点仍非常适用。利用 jQuery,用户可以方便地与 DOM 进行交互,执行 Ajax 请求,创建动画,等等。另外,与 DOM API 不同的是,jQuery 实现了复合模式(composite pattern)。正因为这一特点,你可以在一个 jQuery 集合中调用一些 jQuery 方法,而不用担心集合包含的元素数量(没有、只有一个或很多)。

随着 jQuery 3 的发布,jQuery 会到达一个重要的里程碑。该版本修复了很多 Bug,添加了一些新方法,不建议采用或干脆清除了一批函数,并改变了一些函数的行为。本文将重点介绍 jQuery 3 所带来的一些关键改动。

1 新特性

下面就将逐条介绍 jQuery 所新增的一些关键特性。

1.1 for...of 循环

jQuery 3 现在允许利用 for... Of 来遍历 jQuery 集合的 DOM 元素。这种新的迭代器是 ECMAScript 2015(也就是 ECMAScript 6)规范的一部分。它能实现对可遍历对象(包括 ArrayMapSet 等)的循环。

在使用这一新迭代器时,接收的值并不是每次访问一个元素的 jQuery 集合,而是一个 DOM 元素。这一迭代器稍微改变了对 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++;
}

1.2 $.GET()$.POST() 的新签名

jQuery 3 为 $.get()$.post() 这两个工具函数添加了新的签名,为的是跟 $.ajax() 对等。新的签名是这样的:

$.get([settings])

$.post([settings])

settings 是一种能够执行很多属性的对象,和提供给 $.ajax() 的对象相同。关于详细介绍,请参考 $.ajax() 页面的内容。

跟传递对象给 $.ajax() 相比,当传递对象给 $.get()$.post() 时,其唯一区别在于 method 属性一直被忽略。原因在于 $.get()$.post() 各有一种预设的 HTTP 方法来处理 Ajax 请求($.get()GET$.post()POST)。一般说来,不能用 $.get() 发送 POST 请求。

考虑下面这段代码:

$.get({
   url: 'https://www.audero.it',
   method: 'POST' // 该属性被忽略   
});

尽管有 method 属性,该语句还是不能发送 POST 请求,只能发送 GET 请求。

1.3 动画可以使用 REQUESTANIMATIONFRAME()

所有现代的浏览器,包括 Internet Explorer 10 及更高版本,都支持 requestAnimationFrame。而在这背后,jQuery 3 将在执行动画时使用该 API,从而实现动画更平滑,减少 CPU 的工作压力。

1.4 UNWRAP()

jQuery 3 为 unwrap() 添加了可选的选择器参数。这一方法的新签名为:

unwrap([selector])

有了这一变动,就能将一个包含选择器表达式的字符串传入父元素进行匹配查找。如果存在匹配,那么与之匹配的子元素将解包,否则操作无法完成。

2 已更改的特性

下面是 jQuery 3 已经调整了的一些特性行为。

2.1 :VISIBLE:HIDDEN

新版 jQuery 更改了 :visible:hidden 过滤器的含义。如果元素有布局框,包括那些宽度和/或高度为0的情况,则元素被认为是:visible。比如说,br 元素和没有内容的内联元素将可以通过 :visible 过滤器进行选择。

所以,假如页面有如下标记:

<div></div>
<br />

如果运行了下面语句:

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

那么在 jQuery 1.x 和 2.x 时,结果是 0,而到了 jQuery 3,结果就是 2。

2.2 DATA()

另一改动就是跟 data() 方法的行为有关。调整主要是为了让该方法符合 Dataset API 规范。jQuery 3 将所有属性的键都改为驼峰式大小写形式。先看下面这个例子。

<div id="container"></div>

如果使用 3 之前的版本写了下列代码:

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

$elem.data({
   'my-property': 'hello'
});

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

控制台上的结果如下:

{my-property: "hello"}

而在 jQuery 3,结果为:

{myProperty: "hello"}

所以再次重申:jQuery 3 时,属性名都是驼峰大小写,没有中间的短划线(-);而使用 3 之前的版本,则依然采用全部小写字母的写法,词之间带有短划线。

2.3 Deferred 对象

jQuery 3 还改变了 Deferred 对象的行为(该对象是 Promise 对象的前身),改善了它与 Promise/A+ 提案的兼容性。该对象及其历史非常有意思,你可以读读官方文档,也可以看看我写的书 《jQuery 实战,第 3 版》中有关 jQuery 3 的章节内容。

在 jQuery 1.x 和 2.x 时,传入 Deferred 中的回调函数中的一个未捕获异常会导致程序停止执行。与原生的 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 和 jQuery 2 时,只执行第一个函数(抛出错误的函数)。另外,因为没有为 window.onerror 定义处理器,所以控制台将输出消息:“Uncaught Error: An error”(未捕获的错误:发生错误),程序不再继续执行。

而在 jQuery 3,行为则完全不同了,控制台将显示 “Failure 1” 和 “Success 2” 两个消息。由第一个失败的函数来管理异常,一旦被处理,则继续执行下面的成功函数。

2.4 SVG 文档

jQuery 各个版本(包括 3)都没有对 SVG 文档有过官方的支持。但实际上很多方法都适用,另外一些方法,比如操作类名的方法,已经在 jQuery 3 中进行了更新,因此也适用。因此,在未来的版本中,应该可以使用 addClass()hasClass() 这样的方法处理 SVG 文档,估计不会出现什么问题。

3 过时不建议采用与已清除的方法及属性

除了前面说的改进,jQuery 3 还除去了一些方法和属性,并且声明了一批不建议采用的特性。

3.1 不建议采用:BIND()UNBIND()DELEGATE()UNDELEGATE()

不久前引入的 on() 方法代替了 jQuery 的 bind()delegate() 以及 live() 方法,提供了一种统一的访问接口。与之类似,jQuery 用 off() 方法来代替 unbind()undelegated()die() 方法。bind()delegate()unbind()undelegate() 今后不建议使用,也不会再支持它们。

jQuery 3 将所有这些方法声明为过时,并打算在未来版本中清除它们(有可能是 jQuery 4),所以今后一定要在项目中坚持使用 on()off() 方法,以便适应将来的变化。

3.2 已清除的方法:LOAD()UNLOAD()ERROR()

jQuery 3 完全弃用了已被宣布为过时的方法:load()unload()error()。这些方法已经过时很长时间了(从 jQuery 1.8 起),但仍一直存在着。如果某个插件依赖其中的一个或多个方法,那么更新到 jQuery 3 时,代码就会出错,因此一定要在更新时多注意一下这个问题。

3.3 已清除的属性:CONTEXTSUPPORTSELECTOR

jQuery 3 清除了 contextsupportselector 属性。如前所述,如果项目中仍然使用着这些属性,或者某个插件仍在依赖这些属性,那么更新到 jQuery 3 时,代码就会出错。

4 修复的 Bug

jQuery 3 修复了前一版本的一些重大 Bug。下面介绍两个,此次修复将会对你的编码产生重大影响。

4.1 width()height()

此次修复了 width()height() 以及其他连带方法中的 Bug。这些方法再也不会四舍五入到最近的像素了,因为在某些情况下,这样做很难定位元素。

举例来说明这一问题。假设宽度为 100 px 的 container 元素包含着 3 个子元素。

<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 已经得到修复,你的结果会更精确(比如会得到浮点数)。

4.2 WRAPALL()

jQuery 3 还修复了一个将某个函数传入 wrapAll() 方法时常会出现的 Bug。在 3 之前的版本中,当把某个函数传入 wrapAll() 时,会将 jQuery 集合中的元素分别包装。换句话说,它的行为表现得就像将函数传入 wrap()

除了修复这个问题外,因为这种函数在 jQuery 3 中只会被调用一次,所以jQuery 集合元素的索引不可能被传入。最后,该函数上下文(this)将指向 jQuery 集合中的第一个元素。

5 下载 jQuery 3 beta 1

如果此文让你产生了兴趣,你可以试试 jQuery 3 的第一个 beta 版。通过下面两个 URL 都可以下载到它。

利用 npm 也可以下载它,命令如下:

npm install jquery@3.0.0-beta1

6 总结

许多人宣称 jQuery 已死,认为现代 Web 开发已经不需要它了。但 jQuery 的开发仍在继续,而且统计数字显示,前100万个网站中,采用这一技术的网站占到了 78.5%,从而驳斥了上述反对言论。

本文只是列出了 jQuery 3 所带来的一些主要改变。你可能会注意到,这一版本更新不会对已有项目产生太大的影响,因为没有引入太多破坏性的彻底变革。尽管如此,仍然需要注意一些因素,比如 Deferred 对象的改进。就像更新第三方依赖所经常要面的那样,对项目一定要做一个复查,从而防止意外行为或功能崩溃的情况出现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 原文链接 http://blog.poetries.top/2016/10/20/review-jQuery 关注...
    程序员poetry阅读 16,639评论 18 503
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 1,167评论 0 1
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 1,330评论 0 2
  • 一、样式篇 第1章 初识jQuery (1)环境搭建 进入官方网站获取最新的版本 http://jquery.co...
    凛0_0阅读 3,358评论 0 44