jQuery 3 中的新增功能汇总介绍
从jQuery震撼整个Web,至今已有十年了,我们有很好的理由一直坚持使用维护它。jQuery为用户提供了DOM进行操作,执行Ajax请求,创建动画等等,极为友好的接口。此外,与DOMAPI不同的是,jQuery采用了复合模式(compositepattern)。正因为如此,你可以在一个jQuery集合上调用jQuery方法,而不用担心集合包含的元素数量(零,一个或多个)。
在未来的几周内,随着jQuery3的发布,jQuery会到达一个重要的里程碑。jQuery3修复了很多bug,增加了新的方法,弃用并移除了一些功能,并改变了一些功能的行为。在这篇文章中,我重点讲解jQuery3所带来的一些最大的变化。
新特性(NewFeatures)
在下面的章节中,我将讨论jQuery3中新增的重要特性。
for…of循环
jQuery3将提供for...of循环语句,可以用来遍历一个jQuery集合所有的DOM元素。这种新的迭代器ECMAScript2015(又名的ECMAScript6)规范的一部分。它能实现对可遍历对象(包括Array、Map、Set等)的循环。
当使用这个新的迭代方法时,您每次接收的值不是一个jQuery集合,而是一个DOM元素。当你对一个jQuery集合执行操作时,这个新的迭代方法可以少许改善你的代码。
为了理解这个迭代方法是如何工作的,假设你想给页面中每个input元素分配一个ID。在jQuery3之前,你可以这样写:
var$inputs=$('input'); for(vari=0;i<$inputs.length;i++){ $inputs[i].id='input-'+i; }
而在jQuery3中,你可以这样写:
var$inputs=$('input'); vari=0; for(varinputof$inputs){ input.id='input-'+i++; }
$.get()和$.post()的新签名
jQuery3为$.get()和$.post()工具函数增加了新签名,为的是使得它们和$.ajax()的接口风格保持一致。新签名是这样的:
$.get([settings])
$.post([settings])
settings是一个可以具有许多属性的对象。这是对象和提供给$.ajax()的对象是相同的。更多详细的介绍,详细介绍,请参考$.ajax()页面。
传递给$.get()和$.post()的对象,跟传递给$.ajax()的对象相比,唯一的区别是前者method属性总是会被忽略。其原因是,$.get()和$.post()都有一个预设的HTTP方法来执行Ajax请求($.get()用GET,而$.post()用POST)。一般说来,你不要用$.get()尝试发送POST请求。
考虑下面这段代码:
$.get({ url:'https://www.audero.it', method:'POST'//Thispropertyisignored });
尽管设置了method属性,该语句还是不能发送POST请求,而只能发送GET请求。
采用requestAnimationFrame()来实现动画
所有现代浏览器,包括InternetExplorer10及以上版本,都支持requestAnimationFrame。jQuery3将会在内部采用这个API来实现动画,以便达到更流畅、更省CPU资源的动画效果。
unwrap()
jQuery3为unwrap()方法增加了一个可选的选择器参数。这个方法的新签名为:
unwrap([selector])
有了这一变化,你就可以传入包含一个选择器表达式的字符串,在父元素内进行匹配。如果存在匹配,匹配的子元素将被解包;否则,不进行任何操作。
被变更的特性
jQuery3还修改了一些特性的行为。
:visible和:hidden
jQuery3修改了:visible与:hidden过滤器的含义。只要元素具有任何布局盒,包括那些宽度和/或高度为0的情况,则元素被认为是:visible。比如说,br元素和没有内容的内联元素进可以通过:visible过滤器进行选择。
所以,假如页面有如下标记:
<div></div> <br/>
然后执行下面的语句:
console.log($('body:visible').length);
在jQuery1.x和2.x中,你得到的结果会是0;但在jQuery3中,你会得到2。
data()
另一个重要变化是跟data()方法的行为有关。调整主要是为了让该方法符合DatasetAPI规范。jQuery3将所有属性的键都改为驼峰式大小写形式。要理解这个变化,先看下面这个例子。
<divid="container"></div>
如果你使用jQuery3之前的版本,你可以写如下代码:
var$elem=$('#container'); $elem.data({ 'my-property':'hello' }); console.log($elem.data());
您将在控制台上获得如下结果:
{my-property:"hello"}
而在jQuery3中,你会获得如下结果:
{myProperty:"hello"}
请注意,在jQuery3中,属性名已经变成了驼峰形式,没有横杠(连字符);而在以前的版本中,属性名会保持全小写,并原样保留横杠(连字符)。
Deferred对象
jQuery3改变了Deferred对象的行为,Promise对象的前身,改善与Promise/A+提案的兼容性。这个对象及其历史非常有意思,你可以读读官方文档,或者看看我的书《jQuery实战,第3版》,这本书也涵盖了jQuery3。
在jQuery1.x和2.x中,传入Deferred中的回调函数中如果出现未捕获异常,会导致程序停止执行。而原生的Promise对象并非如此,它会抛出异常,并不断向上冒泡,直至到达window.onerror(通常)。如果你没有定义一个函数来处理这个错误事件的话(通常我们都不会这么做),则会显示异常消息,程序终止执行。
jQuery3会遵循原生的Promise对象的模式。因此,抛出的异常将被视为一个失败状态(rejection),从而执行失败回调。完成之后,整个进程就继续执行,后续的成功回调将被执行。
为了让你更好地理解这个差异,让我们来看一个小例子。考虑下面的代码:
vardeferred=$.Deferred(); deferred .then(function(){ thrownewError('Anerror'); }) .then( function(){ console.log('Success1'); }, function(){ console.log('Failure1'); } ) .then( function(){ console.log('Success2'); }, function(){ console.log('Failure2'); } ); deferred.resolve();
在jQuery1.x和2.x中,只执行第一个函数(抛出错误的函数)会被执行到。此外,由于我们没有为window.onerror定义任何事件处理函数,所以控制台将输出消息:“UncaughtError:Anerror”,而且程序的执行将中止。
而在jQuery3中,行为则完全不同的。你将在控制台中看到“Failure1”和“Success2”两条消息。异常将会被第一个失败回调处理,一旦被处理,则继续执行下面的成功函数。
SVG文档
没有哪一个jQuery版本,包括jQuery3,正式支持SVG文档。不过事实上有很多方法是可以正常工作的,另外一些方法,比如操作类名的方法,已经在jQuery3中进行了更新,因此也适用。因此,在未来的版本中,你应该可以放心使用诸如addClass()和hasClass()这样的方法来操作SVG文档了。
已废弃、已移除的方法和属性
除了前面说的改进,jQuery也移除、废弃了一些特性。
废弃bind(),unbind(),delegate()和undelegate()
jQuery以前引入的on()方法提供了统一的访问接口,取代 bind()、delegate()以及live()方法。与此同时,jQuery用off()方法来取代unbind()、undelegated()及die()方法。bind()、delegate()、unbind()和undelegate()今后不建议使用,但是并没有采取进一步的行动。
jQuery3已经废弃这些方法,并计划在未来的版本(可能是jQuery4)中移除它们,要坚持在项目中使用on()和off()方法,这样你就不用担心未来版本的变更了。
移除load(),unload()和error()方法
jQuery3彻底抛弃了已经废弃的load()、unload()和error()方法。这些方法在很早以前(从jQuery1.8开始)就已经被标记为废弃了,但仍一直存在。如果你正在使用的插件仍然依赖这些方法,那么升级到jQuery3的时候,代码就会出错。因此,在升级过程中要注意。
移除context,support和selector
jQuery3彻底抛弃了已经废弃的context、support和selector属性。如前所述,如果项目中仍然使用着这些属性,或者某个插件仍在依赖这些属性,那么更新到jQuery3时,代码就会出错。
Bugs修复
jQuery3修复了以前版本中的一些重大Bug。在下面的章节中,我将着重介绍其中两处,因为这两处会对你的编码产生重大影响
width()和height()的返回值不再四舍五入
jQuery3修复了width()、height()和其它相关方法中的一个bug。这些方法的返回值将不再四舍五入取整到像素了,因为,这使得在某些情况下很难,对元素进行定位。
要理解这个问题,让我们假设你有一个具有100像素的宽度的容器元素,这个元素有宽度均为三分之一(即33.333333%)的3个子元素:
<divclass="container"> <div>Myname</div> <div>is</div> <div>AurelioDeRosa</div> </div>
在jQuery3以前的版本中,如果你尝试通过以下代码来获取子元素的宽度……
$('.containerdiv').width();
……那么你得到结果将是33。原因在于jQuery会将33.33333这个值四舍五入取整。而在jQuery3中,这个Bug已经得到修复,你的结果会更精确(比如会得到浮点数)。
wrapAll()
jQuery的新版本中还修复wrapAll()方法的一个bug,这个bug会在传递一个函数给wrapAll()方法时发生。在jQuery3以前的版本中,当一个函数被传给wrapAll()方法时,它会把jQuery集合中的每个元素单独包裹起来。换句话说,这种行为和把一个函数传给wrap()时的行为是完全一样的。
除了修复这个问题,因为这种函数在jQuery3中只会被调用一次,所以jQuery集合元素的索引不可能被传入。最后,该函数上下文(this)将指向jQuery集合中的第一个元素。
下载jQuery3
您可以从jQueryCDN获取文件,或者直接访问链接:
https://code.jquery.com/jquery-3.0.0.js
https://code.jquery.com/jquery-3.0.0.min.js
您也可以从以下npm获得更新:
npminstalljquery@3.0.0
总结
很多人在说jQuery已死,认为在现代网页开发中已经没有一席之地了。然而,jQuery的开发仍在继续,客观的统计数据(在排名前一百万名的网站中占有率高达78.5%)驳斥这些说法。
在本文中,我已经带你了解了一遍jQuery3将会带来的一些重大变化。或许你已经注意到了,这个版本是可能对你现有的项目产生太大的影响,因为没有引入太多许多重大更改。尽管如此,仍然需要注意一些因素,比如Deferred对象的改进。就像更新第三方依赖所经常要面的那样,对项目一定要做一个复查,从而防止意外行为或功能崩溃的情况出现。