w3ctech

[译]jQuery3中的变化

原文由Aurelio De Rosa编写于2016年3月2日。

在web上使用jQuery已经流行了将近十年了。jQuery为他的用户提供了易用的接口来和DOM进行交互、执行ajax请求、创建动画和完成其他任务。此外,不同于DOM的API,jQuery实现了复合模式。因此,你可以为一个jQuery集合调用jQuery方法而不用考虑集合里面的元素数量(零个、一个或者很多个)。

几周后,随着第三版本的发布,jQuery会达到一个新的里程碑。jQuery3修复了大量的bug、添加了新方法、弃用并移除了一些方法并且更改了一些方法的行为。在这篇文章里,我将会重点介绍一些jQuery3引入的重要变更。

新特性

在接下来这部分,我会讨论jQuery3添加的的重要新特性。

  • FOR...OF循环

jQuery3会提供使用for...of循环来遍历jQuery集合中的DOM元素的可能性。这种新的迭代器是ECMAScript2015(又名ECMAScript6)规范中的一部分。它让你可以遍历可遍历的对象(包括数组、映射、集合等等)。

当使用这个新的迭代器的时候,你获得的值将不再是一个每次只能获取一个元素的jQuery集合,而是一个DOM元素。这个迭代器将稍微提高你对jQuery集合操作的方式。

为了明白这个迭代器是怎样工作的,我们举个例子。假设,你想为页面里的每个input元素分配一个ID。在jQuery3之前,你是这么写的:

var $inputs = $('input');

for(var i = 0; i < $inputs.length; i++) {
   $inputs[i].id = 'input-' + i;
}

在jQuery3中你可以这么写。

var $inputs = $('input');
var i = 0; 

for(var input of $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' // This property is ignored
});

尽管有方法属性,但是这个表达式仍然是是发出一个GET请求而不是一个POST请求。

  • 在动画中使用REQUESTANIMATIONFRAME()

所有的现代浏览器,包括IE10及以上版本,都支持requestAnimationFrame方法。在幕后,jQUery3会在进行动画的时候使用这个API来使动画更平滑并且占用更少CPU。

  • UNWRAP()

jQuery3添加了一个可选的参数来执行unwrap()方法。这个方法的新特征是:

unwrap([selector])

由于这个变化,你可以传入一个选择器表达式的字符串来在父元素中进行匹配。如果匹配,匹配的子元素的父元素会被删除,否则,这个操作不会执行。

变化的特征

jQuery也更改了一些功能的行为。

  • :VISIBLE:HIDDEN

新版本的jQuery改变了:visible:hidden过滤器的意义。任何具有布局箱的元素都会被视为:visible,包括哪些宽高为0的元素。例如,br元素和没有内容的内敛元素都会被:visible过滤器选择。

所以,如果你在页面上有如下标记:

<div></div>
<br />

然后你执行了以下语句:

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

在jQuery1.x版本或者2.x版本,你会获得0,但是在版本3中你会获得2.

  • DATA()

另外一个重要改变和data()方法的行为有关。它已经被更改来与数据集API规范看齐。jQuery3会把所有的属性键转换为驼峰表示,我们看看下面这个例子:

<div id="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 in Action第三版,他也覆盖了jQuery3。

在jQuery1.x和2.x版本中,如果在传入Deferred的回调函数中有一个未捕捉的异常会暂停程序的执行。不像原生的Promise对象,被抛出的异常会(通常)一直冒泡直到到达window层。如果你还没有定义一个函数来接受这个事件(这种事情是很罕见的),异常信息会被展示,程序执行被中断。

jQuery3遵从与原生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();

在jQuery1和jQuery2中,只有第一个函数(抛出异常的函数)被执行。另外,因为我没有定义任何window层面的处理器,一旦出错,控制台信息就会输出“Uncaught Error: An error”并且中止程序的执行。

在jQuery3中,行为完全不同了。你会看到“Failure 1”和“Success 2”在控制台上被输出。异常被第一个failure函数处理,一旦他被管理起来了,下一个success函数就会被执行。

  • SVG文件

没有jQuery版本,包括jQuery3,官方支持SVG文件。然而,事实上是,许多方法都可以使用,而其他,如处理类的名称,在jQuery3中被升级所以可以使用。因此,在这个即将到来的jQuery版本,你可以在svg文件中使用方法如addClass()和hasClass()并且运行正常。

被弃用或者移除的方法和属性

除了目前提到的改进,jQuery也移除了和弃用了一些特征。

  • BIND(),UNBIND(),DELEGATE()和UNDELEGATE()的降级

on()方法已经被引进有一段时间来提供一个统一接口用于取代jQuery的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摆脱了已经被废弃的contextsupportselector属性。就像我在之前的章节提到那样,如果你依然要在你的项目中使用它们或者你使用了依赖他们的的插件,升级jQuery3会破坏你的代码。

被修复的Bugs

jQuery3修复了一些之前版本中的重要bug。在下一个章节,我会提到两个可能会给你的工作带来巨大变化的bug。

  • 不再为width()和height()进行四舍五入

jQuery3修复了width()、height()和其他相关方法的bug。这些方法将不再四舍五入到最近的像素值,之前这让我们在某些情况下难以定位元素。

要理解这些问题,假设你现在有三个元素,宽度是1/3(33.333333%)父元素,父元素的款式100培训:

<div class="container">
   <div>My name</div>
   <div>is</div>
   <div>Aurelio De Rosa</div>
</div>

在jQuery3之前,如果你尝试通过以下方法去获得子元素的宽度。

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

你会获得33作为结果。这是因为jQuery作了四舍五入的处理。在jQuery3中,这个bug被修复了,所以你可以获得一个更精确的值(如一个浮点数值)。

  • WRAPALL()

新版本的jQuery修复了当传入一个函数到wrapAll()方法中时出现的一个bug。在jQuery3之前,当传入一个函数的时候,他独立地包裹jQuery集合中的每个元素。换句话来说,他和传入一个函数到wrap()中是一样的。

除了修复这个问题之外,既然这个函数在jQuery3中只会被调用一次,他不会把jQuery集合中的元素索引传入到函数中。最后,函数的上下文(this)将引用自jQuery集合中的第一个元素。

下载jQuery3 beta1版本

如果这篇文章提起了你的新区,你可能想试试jQuery3的beta版本1.你可通过下面两个URL来获取。

你也可以通过以下命令在npm来下载:

npm install jquery@3.0.0-beta1

结论

许多人宣称jQuery已死和他在现代web发张中已经没有地位了。然而,他仍然在发展并且他的使用率(在超过百万级访问量的网站中78.5%使用了jQuery)和这种论调相反。

在这篇文章中,我带你看了一些jQuery3中的主要变化。你可能会注意到,这个版本不会打破你现存的项目,因为他没有十分大的变化。尽管如此,仍然有一些要点诸如Deferred对象的改进需要在升级的时候注意。在做第三方依赖更新前,对项目进行一次review会帮助你发现那些不期望的行为和可能会被破坏的功能。

w3ctech微信

扫码关注w3ctech微信公众号

共收到1条回复

  • 从此大on一统江湖~

    回复此楼