返回 导航

其他

hangge.com

jQuery - jQuery3的新特性汇总(附样例)

作者:hangge | 2018-12-13 08:10
    jQuery 由于易学易用的特性受到许多前端开发者的欢迎。而最新的 jQuery 3 其实在 2016 年就已经发布了,但由于种种原因:比如不兼容老的 IE 浏览器(ie6/7/8)、很多插件还不支持、老版本的 jQuery 功能也完全够用了......造成 jQuery 3 的使用率一直很低。
    其实不同于 jQuery 2 主要做的是性能的提升,jQuery 3 是实实在在增加了许多新特性,本文我就对这些新特性做个汇总。

一、新增的特性

1,支持 for...of 循环语句

jQuery 3 中,我们可以用 for...of 循环语句来迭代一个 jQuery 集合中的所有 DOM 元素。这种新的迭代方法是 ECMAScript 2015(即 ES6)规范中的一部分。这个方法可以对 “可迭代对象”(比如 ArrayMapSet 等)进行循环。

(1)比如过去我们使用 for 循环遍历页面上的所有 input 元素,并修改它的 ID,可以这么写:
for(var i = 0; i < $('input').length; i++) {
  $('input')[i].id = 'input-' + i;
}

(2)使用新的 for...of 循环怎可以这么写:
var i = 0;
for(var input of $('input')) {
   input.id = 'input-' + i++;
}

注意:for...of 循环体内每次拿到的值并不是一个 jQuery 对象,而是一个 DOM 元素。这一点跟 jQuery 自己提供的 .each() 方法类似。
$('input').each(function(index,item){
  item.id = 'input-' + index;
});

2,$.get() 和 $.post() 增加了新的参数类型 [settings]

(1)jQuery 3$.get() $.post() 这两个方法增加了新的参数类型 [settings],从而使得它们和 $.ajax() 的接口风格保持一致。
 //过去这么写
 $.post('test.php', { name: 'hangge', age: 2 }, function (data) {
   console.log(data);
 });

 // jQuery3 中可以这样写
 $.post({
   url: 'test.php',
   data: { name: 'hangge', age: 2 },
   success: function (data) {
     console.log(data);
   }
 });

(2)与 $.ajax() 唯一不同的是:如果 $.get()$.post()[settings] 中传递了 method 属性,method 的属性值将被忽略掉。
$.get({
  url: 'test.php',
  method: 'POST'  //这个将被忽略,仍然是get请求
});

3,采用 requestAnimationFrame() 来实现动画

之前的版本中,jQuery 使用 setInterval 通过不断更新元素的 CSS 属性产生动画。每次更新时会迫使浏览器对页面进行重绘(reflow),而一般显示器 16.7ms 刷新一次,如果在这间隔期间有其他的 setInterval 请求,就会导致”帧”丢失,造成动画卡顿。
(1)现在几乎所有的现代浏览器(包括 IE 10 及以上版本),都支持 requestAnimationFramerequestAnimationFrame 会根据浏览器的绘制时间 对动画进行不断优化,使动画流畅并减少对 CPU 资源的消耗。
(2)而 jQuery 3 会使用这个 API 执行动画,让动画的播放更加顺畅、速度更快。

4,unwrap() 方法增加一个可选参数 selector

(1)我们知道使用 unwrap() 方法可以删除被选元素的父元素。
<script type="text/javascript">
   $(function() {
     $("input").unwrap();
   });
</script>
<div class="wrapper1">
  <div class="wrapper2">
    <input type="text">
  </div>
</div>

(2)jQuery 3 unwrap() 方法增加了一个可选参数 selector,我们可以通过这个字符串选择器匹配元素的父元素:
  • 如果匹配到:则移除父元素
  • 如果没有匹配到:就不移除父元素
$("input").unwrap(".wrapper3"); //由于没有匹配到,则不会移除父元素

5,addClass()、removeClass()、toggleClass() 方法可以接受类数组

(1)过去想要通过 addClass()removeClass()toggleClass() 方法一次性设置多个类时,需要使用空格分开多个 class
$("#div1").addClass("important blue");

(2)而从 jQuery 3.3 起,这些方法可以直接接受类数组。
$("#div1").addClass(["important", "blue"]);

6,新增了 $.escapeSelector() 方法

(1)jQuery 3 新增的 $.escapeSelector() 函数可以用来转义 CSS 选择器中有特殊意义的字符或字符串。此方法对于一个 CSS 类名或一个 ID 包含的字符在 CSS 中具有特殊含义的情况下非常有用,如点或分号。
(2)下面是一个简单的样例:
<div id="#div1">hangge.com</div>
<div class="abc.def">hangge.com</div>

//如果像下面这么写会直接报错
$('##div1').text();
$('.abc.def').text();

//$.escapeSelector()就是用来解决这个问题
$('#' + $.escapeSelector('#div1')).text();
$('.' + $.escapeSelector('abc.def')).text();

二、有变更的特性

1,:visible 和 :hidden 过滤器含义变更

(1)jQuery 3 修改了 :visible :hidden 过滤器的定义。任何可用于布局的元素 即使它们的高度宽度为 0,都会被认为是 :visible
(2)比如 <br> 元素和没有内容的内联元素,现在都会被 :visible 过滤器匹配。
<body>
  <div></div>
  <br/>
</body>

//在 jQuery 1.x 和 2.x 中,你得到的结果会是 0
//在 jQuery 3.x,你得到的结果会是 2
console.log($('body :visible').length);

2,data() 方法

(1)现在 data() 方法行为已经变得跟 Dataset API 规范一致。jQuery 3 将会把所有属性键名转换成驼峰形式。
(2)比如下面一个样例:
  • jQuery 1.x2.x 中:属性名会保持全小写,并原样保留横杠。
  • jQuery 3.x:属性名已经变成了驼峰形式,横杠已经被去除了。
/*******************************
    测试样例
********************************/
<div id="container"></div>

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

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

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


/*******************************
    jQuery 1.x 和 2.x 结果
********************************/
{my-property: "hello"}


/*******************************
    jQuery 3.x 结果
********************************/
{myProperty: "hello"}

3,Deferred 对象

Deferred 对象可以说是 Promise 对象的前身之一,它实现了对 Promise/A+ 协议 的兼容。关于 Deferred 更详细的用法可以参考我之前写的这篇文章:
(1)jQuery 3 改变了 deferred 对象的行为,使得 deferred 对象可与新的 Promises/A+ 标准兼容。deferred 对象成为了可链对象,让创建回调队列成为可能。 
  • jQuery 1.x2.x 中:传递给 deferred 的回调函数内如果出现未捕获的异常,就会阻断程序的执行。不像原生 Promise 对象那样会抛出异常冒泡至 window.onerror(通常冒泡到这里)。如果你没有定义一个函数处理错误事件(通常我们是会处理的),那么异常信息就会显示并且程序会终止执行。
  • jQuery 3.x 中:jQuery3 遵循原生 Promise 对象的模式。因此,抛出的异常被当作失败,接着失败回调函数被执行。一旦失败回调函数执行完成,进程就会继续,下面的成功回调函数将被执行。

(2)下面是一个简单的样例:
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”两条消息。那个异常将会被第一个失败回调处理,并且,一旦异常得到处理,那么后续的成功回调将被调用。

4,类操作方法支持 SVG

(1)可惜的是,jQuery 现在还无法完全支持 SVG(包括 jQuery3)。
(2)但是在 jQuery 3 中,对于操作 CSS 类名称的 jQuery 方法,如 addClass() 和 hasClass() 现在可以将 SVG 文档作为目标。这意味着,我们可以修改(添加、移除、切换),或是寻找 SVG 下的 jQuery 类,然后使用 CSS 的样式。 

三、已废弃、已移除的方法和属性

废弃与移除的区别:
  • 废弃:是指一些方法还在存在于 jQuery 源码中,但是已经提供了新方法来替换那些方法。
  • 移除:是指一些方法已经从 jQuery 源码中删除了。

1,废弃 bind()、unbind()、delegate() 和 undelegate() 方法

(1)在很早之前,bind()delegate()unbind()undelegate() 就已经不再推荐使用了,但它们还是一直存在着:
  • jQuery 在很久以前就引入了 on() 方法,它提供了一个统一的接口,用以取代 bind()delegate()live() 等方法。
  • 同时,jQuery 还引入了 off() 这个方法来取代 unbind()undelegated() die() 等方法。

(2)jQuery 3 终于开始将这些方法标记为 “废弃” 了,并计划在未来的某个版本(很可能是 jQuery 4)中将它们彻底移除。因此,建议我们在项目中统一使用 on() off() 方法,这样就不用担心未来版本的变更了。

2,移除 load()、unload() 和 error() 方法

load()unload() error() 等方法在很早以前(从 jQuery 1.8 开始)就已经被标记为废弃了,但一直没有去掉。这次 jQuery 3 彻底将它们移除了。

3,移除 context、support 和 selector 属性

jQuery3 移除了已经废弃的 contextsupport selector 属性。

四、修复了之前版本中存在的重大 Bug

1,width() 和 height() 的返回值将不再取整

(1)在 jQuery 3 中,width()height() 及所有其它相关方法将不再将结果的像素值四舍五入到一个整数值,因为四舍五入后在某些情况下很难对元素进行定位。
(2)比如下面样例,container 容器内有三个子元素,它们宽度均为父容器的 1/3。我们通过 width() 得到具体的宽度值:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hangge.com</title>
    <script src="js/jquery-3.3.1.min.js" charset="utf-8"></script>
    <script type="text/javascript">
       $(function() {
         var width = $('.container div').width()
         console.log(width);
       });
    </script>
    <style>
      .container div {
        width: 33.3333%;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div>My name</div>
      <div>is</div>
      <div>Aurelio De Rosa</div>
    </div>
  </body>
</html>

  • jQuery 1.x 2.x 中,输出结果如下:

  • jQuery 3.x 中,输出结果如下:

2,wrapAll() 方法

(1)jQuery 3 还修复了 wrapAll() 方法中的一个 bug,这个 bug 出现在把一个函数作为参数传给它的情况下。在 jQuery 3 以前的版本中,当一个函数被传给 wrapAll() 方法时,它会把 jQuery 集合中的每个元素单独包裹起来。换句话说,这种行为和把一个函数传给 wrap() 时的行为是完全一样的。
(2)在修复这个问题的同时,还引入了另外一个变更:由于在 jQuery 3 中,这个函数只会调用一次了,那就无法把 jQuery 集合中每个元素都传给它。因此,这个函数的执行上下文(this)将只能指向当前 jQuery 集合中的第一个元素。
评论

全部评论(0)

回到顶部