[译] jQuery 3 有哪些新东西
转自:https://github.com/cssmagic/blog/issues/59
jQuery 的横空出世,至今已有十个年头了,而它的长盛不衰显然不是没有理由的。jQuery 提供了极为友好的接口,使得开发者们可以方便地进行 DOM 操作、发起 Ajax 请求、生成动画……不一而足。此外,与 DOM API 不同的是,jQuery 采用了 “混合模式”。这意味着你可以在任何一个 jQuery 集合身上调用 jQuery 方法,而不用关心它到底包含了几个元素(不管是零个、一个或多个,都没问题)。
在未来的几周内,jQuery 就将抵达一个重要的里程碑——正式发布 3.0 版本。jQuery 3 修复了大量的 bug,增加了新的方法,同时移除了一些接口,并修改了少量接口的行为。在这篇文章中,我将为大家重点讲解 jQuery 3 所引入的那些最重要的变化。
New Features
新增特性
我们先来讨论 jQuery 3 中最重要的几个新增特性。
for...of
Loop
for...of
循环
在 jQuery 3 中,我们可以用 for...of
循环语句来迭代一个 jQuery 集合中的所有 DOM 元素。这种新的迭代方法是 ECMAScript 2015(即 ES6)规范中的一部分。这个方法可以对 “可迭代对象”(比如Array
、Map
、Set
等)进行循环。
当使用这种新的迭代方法时,你在循环体内每次拿到的值并不是一个 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()
方法的,可读性也不赖。)
New signature for $.get()
and $.post()
$.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://funteas.com' , method: 'POST' // 这个属性将被忽略 }); |
不管我们把 method
属性写成什么,这个请求总是会以 GET 的方式发出去的。
Use of requestAnimationFrame()
for Animations
采用 requestAnimationFrame()
来实现动画
所有现代浏览器(包括 IE10 及以上)都是支持 requestAnimationFrame
的。jQuery 3 将会在内部采用这个 API 来实现动画,以便达到更流畅、更省资源的动画效果。
unwrap()
unwrap()
方法
jQuery 3 为 unwrap()
方法增加了一个可选的 selector 参数。这个方法的新签名是这样的:
unwrap([selector]) |
有了这个特性,你就可以给这个方法传入一个包含选择符表达式的字符串,用它来在父元素内进行匹配。如果存在匹配的子元素,则这个子元素的父层将被解除;如果没有匹配,则不进行操作。
Features Changed
有变更的特性
jQuery 3 还修改了一些特性的行为。
:visible
and :hidden
: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()
方法
另一个重要的变化是跟 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 中,属性名已经变成了驼峰形式,横杠已经被去除了;而在以前的版本中,属性名会保持全小写,并原样保留横杠。
The Deferred
Object
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 Documents
SVG 文档
没有哪一个 jQuery 版本(包括 jQuery 3)曾官方宣称支持 SVG 文档。不过事实上有很多方法是可以奏效的,此外还有一些方法在以前是不行的(比如操作类名的那些方法),但它们在 jQuery 3 中也得到了更新。因此,在 jQuery 3 中,你应该可以放心使用诸如 addClass()
和 hasClass()
这样的方法来操作 SVG 文档了。
Methods and Properties Deprecated or Removed
已废弃、已移除的方法和属性
在增加了上述改进的同时,jQuery 也移除、废弃了一些特性。
Deprecation of bind()
, unbind()
, delegate()
and undelegate()
废弃 bind()
、unbind()
、delegate()
和 undelegate()
方法
jQuery 在很久以前就引入了 on()
方法,它提供了一个统一的接口,用以取代 bind()
、delegate()
和live()
等方法。与此同时,jQuery 还引入了 off()
这个方法来取代 unbind()
、undelegated()
和die()
等方法。从那时起,bind()
、delegate()
、unbind()
和 undelegate()
就已经不再推荐使用了,但它们还是一直存在着。
jQuery 3 终于开始将这些方法标记为 “废弃” 了,并计划在未来的某个版本(很可能是 jQuery 4)中将它们彻底移除。因此,请在你的项目中统一使用 on()
和 off()
方法,这样你就不用担心未来版本的变更了。
Removal of the load()
, unload()
and error()
Methods
移除 load()
、unload()
和 error()
方法
jQuery 3 彻底抛弃了 load()
、unload()
和 error()
等已经标记为废弃的方法。这些方法在很早以前(从 jQuery 1.8 开始)就已经被标记为废弃了,但一直没有去掉。如果你正在使用的某款插件仍然依赖这些方法,那么升级到 jQuery 3 会把你的代码搞挂。因此,在升级过程中请务必留意。
Removal of context
, support
and selector
移除 context
、support
和 selector
属性
jQuery 3 彻底抛弃了 context
、support
和 selector
等已经标记为废弃的属性。同上,在升级到 jQuery 3 时,请留意你正使用的插件。
Bugs fixed
已修复的 Bug
jQuery 3 修复了以往版本中的一些非常重要的 bug。在本节中,我将着重介绍其中两处,因为这两者应该会对你写代码的习惯带来显著影响。
No More Rounding for width()
and height()
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()
wrapAll()
方法
jQuery 3 还修复了 wrapAll()
方法中的一个 bug,这个 bug 出现在把一个函数作为参数传给它的情况下。在 jQuery 3 以前的版本中,当一个函数被传给 wrapAll()
方法时,它会把 jQuery 集合中的每个元素单独包裹起来。换句话说,这种行为和把一个函数传给 wrap()
时的行为是完全一样的。
在修复这个问题的同时,还引入了另外一个变更:由于在 jQuery 3 中,这个函数只会调用一次了,那就无法把 jQuery 集合中每个元素都传给它。因此,这个函数的执行上下文(this
)将只能指向当前 jQuery 集合中的第一个元素。
Downloading jQuery 3 beta 1
如何下载 jQuery 3 beta 1
既然你已经读到了这里,那说明你很可能想试试 jQuery 3 的第一个 beta 测试版。你可以通过以下两个地址来获取这个版本:
Non-minified version: https://code.jquery.com/jquery-3.0.0-beta1.js
Minified version: https://code.jquery.com/jquery-3.0.0-beta1.min.js
当然,你还可以通过 npm 来下载:
npm install jquery @3 .0.0-beta1 |
Conclusion
结论
很多人一直在唱衰 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 不兼容的地方。当你修复了这些不兼容问题之后,就可以安全地移除这个插件了。
[译] jQuery 3 有哪些新东西的更多相关文章
- jQuery 3 有哪些新东西
jQuery 的横空出世,至今已有十个年头了,而它的长盛不衰显然不是没有理由的.jQuery 提供了极为友好的接口,使得开发者们可以方便地进行 DOM 操作.发起 Ajax 请求.生成动画……不一而足 ...
- ES6 有什么新东西
ES6 有什么新东西? 你可能已经听说过 ECMAScript 6 (简称 ES6)了.ES6 是 Javascript 的下一个版本,它有很多很棒的新特性.这些特性复杂程度各不相同,但对于简单的脚本 ...
- 【转发】jquery实现自动打开新的页签
通常我们想要浏览器在回调方法中打开一个页签,用这个方法 //window.open("http://www.baidu.com") ; //自动打开新窗口,会被浏览器拦 ...
- [翻译] 预览 C# 10 的新东西
原文: [Introducing C# 10] 作者: Ken Bonny 本周早些时候(译注:原文发表于5月1日),我关注了 Mads Torgersen 在 DotNet SouthWest ...
- 什么新东西值得学「GitHub 热点速览 v.22.29」
上周 18k+ 的项目 bun 这周又获得 7k+ star,是时候了解下它背后的编程语言 zig 了,它并不是一门新的语言,伴随着 bun 的风靡,zig 本周也上了 GitHub 热榜.同样,可以 ...
- 新的一年快开始了,学点新东西吧,从React开始(一)
ReactJS是Facebook出的前端View框架,好东西啊. 看看它的说明: 仅仅是UI 许多人使用React作为MVC架构的V层. 尽管React并没有假设过你的其余技术栈, 但它仍可以作为一个 ...
- jquery 选择器 -高级使用 新的 心得
jQuery的each函数: each函数等同于c语言中的for函数: 里面每次循环的 "context 上下文" == 当前的dom ,可以使用this, 也可以使用$(this ...
- 封装jquery时用到的东西
顺序都是瞎拍的,就是明显分割用 1.将函数封装成$(' ')这种形式 把函数名起成$ $(各种选择器) $(selector) 2.有时候jquery可以继续加点,返回自己本身的元素 创建个构造函数, ...
- [extjs5学习笔记]第三十七节 Extjs6预览版都有神马新东西
本文在微信公众号文章地址:微信公众号文章地址 本文地址:http://blog.csdn.net/sushengmiyan/article/details/45190485 [TOC] 在Ext JS ...
随机推荐
- eclipse for php现有项目不能导入问题
1.少了.project文件 解决办法:创建一个新项目,然后将新项目文件夹下的.project文件复制到将要导入的文件夹中.
- python多线程学习记录
1.多线程的创建 import threading t = t.theading.Thread(target, args--) t.SetDeamon(True)//设置为守护进程 t.start() ...
- 生成解决方案,主项目的bin目录下没有其他项目生成的dll
问题说明: 我的项目组成: 主项目为:TaskUtlity 在生成解决方案的时候在TaskUtlity的bin目录下老是找不到ProBonus项目生成的dll. 解决方案: 1.打开sln文件,找到P ...
- 【Maven】运行项目
1.run as maven clean 清除原有的编译结果重新编译一次. 2.run as maven bulid.. goals:package tomcat7:deploy 打包到Tomcat7 ...
- SQL的ROW_NUMBER函数
with tabs as ( select ROW_NUMBER() over(partition by customerID order by totalPrice) as rows,custome ...
- vbox中虚拟ubuntu增加新的虚拟硬盘
vbox中虚拟ubuntu增加新的虚拟硬盘 在virtualbox中装好Ubuntu后,发现硬盘空间不够使用 了.以下是搜集整理的解决办法: 1. 添加新硬盘 设置 -> ...
- 【python】装饰器
来源:廖雪峰 看了好多次装饰器,发现还是廖老师讲得好,能让我看懂..... 下面是一段装饰器代码 @log def now(): " 它的含义等价于 def now(): " no ...
- C语言指针类型
1:只要是指针类型,不管是几级指针[带几个*],其宽度都是4字节 2:任何数据类型[包括自己定义的结构体]前面都能加*号,表示该数据类型的一个指针 3:由于是386处理器,其数据处理的宽度都是四个字节 ...
- Linux C编程学习之C语言简介---预处理、宏、文件包含……
C的简介 C语言的结构极其紧凑,C语言是一种模块化的编程语言,整个程序可以分割为几个相对独立的功能模块,模块之间的相互调用和数据传递是非常方便的 C语言的表达能力十分强大.C语言兼顾了高级语言和汇编语 ...
- .NET中RabbitMQ的使用
概述 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public ...