jQuery 3.0 版本候选…发布!

发布日期 作者

欢迎使用 jQuery 3.0 的版本候选!这是我们预计将发布为 jQuery 3.0 окончательного версии 的相同代码(如果有重大错误或回归,则可能会更改)。发布后,jQuery 3.0 将成为 jQuery 的唯一版本。1.12 和 2.2 分支将继续接收关键支持补丁一段时间,但不会获得任何新功能或重大修订。请注意,jQuery 3.0 不支持 IE6-8。如果您需要 IE6-8 支持,您可以继续使用最新的 1.12 版本。

尽管版本号为 3.0,但我们预计这些版本在升级现有代码时应该不会太麻烦。是的,有一些“重大更改”证明了主版本升级的合理性,但我们希望这些更改实际上不会影响太多人。

为了帮助您进行升级,我们推出了全新的 3.0 升级指南。另外,jQuery Migrate 3.0-rc 插件 将帮助您识别代码中的兼容性问题。您对更改的反馈将对我们非常有帮助,因此请在您的现有代码和插件上试用一下!

您可以从 jQuery CDN 获取文件,也可以直接链接到它们

https://code.jqueryjs.cn/jquery-3.0.0-rc1.js

https://code.jqueryjs.cn/jquery-3.0.0-rc1.min.js

您也可以从 npm 获取版本候选

npm install jquery@3.0.0-rc1

此外,我们还提供了 jQuery Migrate 3.0 的版本候选。我们强烈建议您使用它来解决 jQuery 3.0 中的任何重大更改问题。您可以从此处获取这些文件

https://code.jqueryjs.cn/jquery-migrate-3.0.0-rc1.js

https://code.jqueryjs.cn/jquery-migrate-3.0.0-rc1.min.js

npm install jquery-migrate@3.0.0-rc1

有关使用 jQuery Migrate 将您的 jQuery 1.x 和 2.x 页面升级到 jQuery 3.0 的更多信息,请参见昨天的 jQuery Migrate 博客文章

 

重大更改

以下是这些版本中主要新功能、改进和错误修复的重点,您可以深入了解 3.0 升级指南。已修复问题的完整列表可在我们的 GitHub 错误跟踪器 上找到。

jQuery.Deferred 现在与 Promises/A+ 兼容

jQuery.Deferred 对象已更新以与 Promises/A+ 和 ES2015 Promises 兼容,并已使用 Promises/A+ 兼容性测试套件 验证。这意味着我们需要对 .then() 方法进行一些重大更改

  • .then() 回调中抛出的异常现在将成为拒绝值。以前,异常会一直冒泡到最顶层,中止回调执行并不可逆地锁定父级和子级 Deferred 对象。
  • .then() 创建的 Deferred 的解析状态现在由其回调控制——异常将成为拒绝值,非 thenable 返回将成为完成值。以前,拒绝处理程序中的返回值将成为拒绝值。
  • 回调始终异步调用。以前,它们会在绑定或解析之后立即调用,以最后发生的事件为准。

考虑以下情况,其中父级 Deferred 被拒绝,而子级回调会生成异常


var parent = jQuery.Deferred();
var child = parent.then( null, function() {
  return "bar";
});
var callback = function( state ) {
  return function( value ) {
    console.log( state, value );
    throw new Error( "baz" );
  };
};
var grandchildren = [
  child.then( callback( "fulfilled" ), callback( "rejected" ) ),
  child.then( callback( "fulfilled" ), callback( "rejected" ) )
];
parent.reject( "foo" );
console.log( "parent resolved" );

从 jQuery 3.0 开始,这将在调用任何回调之前记录“父级已解析”,然后每个子级回调将记录“已完成 bar”,而孙级将被拒绝,并显示错误“baz”。在以前的版本中,这将记录“拒绝 bar”(子级 Deferred 被拒绝而不是完成)一次,然后立即终止,并出现未捕获的错误“baz”(“父级已解析”未被记录,而孙级仍未解析)。

虽然捕获到的异常对于浏览器内调试有优势,但使用拒绝回调处理它们更具声明性(即显式)。请记住,这要求您在使用 promise 时始终添加至少一个拒绝回调。否则,任何错误都将被忽略。

可以通过将 .then() 的使用替换为现在已弃用的 .pipe() 方法(它具有相同的签名)来恢复旧的行为。

我们还构建了一个插件来帮助调试与 Promises/A+ 兼容的 Deferred。如果您在控制台上看不到有关错误的足够信息来确定其来源,请查看 jQuery Deferred Reporter 插件

jQuery.when 也已更新,可以接受任何 thenable 对象,其中包括原生 Promise 对象。

https://github.com/jquery/jquery/issues/1722
https://github.com/jquery/jquery/issues/2102

向 Deferred 添加 .catch()

catch() 方法已添加到 promise 对象中,作为 .then(null, fn) 的别名。

https://github.com/jquery/jquery/issues/2102

错误情况不会静默失败

也许在某个深刻的时刻,您会想,“窗口的偏移量是多少?”然后您可能意识到这是一个疯狂的问题——窗口怎么可能有偏移量?

过去,jQuery 有时会尝试让这样的情况返回某些东西,而不是让它们抛出错误。在这种特定情况下,询问窗口的偏移量,到目前为止的答案是 { top: 0, left: 0 }。使用 jQuery 3.0,这些情况将抛出错误,以便不会静默忽略疯狂的请求。请尝试使用此版本,看看是否有任何代码依赖于 jQuery 来掩盖无效输入带来的问题。

https://github.com/jquery/jquery/issues/1784

已删除已弃用的事件别名

.load.unload.error 从 jQuery 1.8 开始已弃用,现在已不再存在。使用 .on() 注册侦听器。

https://github.com/jquery/jquery/issues/2286

动画现在使用 requestAnimationFrame

在支持 requestAnimationFrame API 的平台上,也就是除了 IE9 和 Android<4.4 之外的几乎所有平台,jQuery 在执行动画时现在将使用该 API。这应该会导致动画更加流畅,并减少 CPU 时间使用——并为移动设备节省电池电量。

jQuery 尝试在几年前使用 requestAnimationFrame,但遇到了 严重的兼容性问题,因此我们不得不将其回滚。我们认为,通过在浏览器选项卡处于隐藏状态时暂停动画,我们已经解决了大多数这些问题。不过,任何依赖于动画始终以几乎实时方式运行的代码都做出了不切实际的假设。

某些 jQuery 自定义选择器速度大幅提升

由于 Google 的 Paul Irish 的一些调查工作,我们发现了一些情况,在这些情况下,当在同一文档中多次使用 :visible 等自定义选择器时,我们可以跳过大量额外工作。现在,这种情况的执行速度提高了 17 倍!

请记住,即使有了这种改进,:visible:hidden 等选择器也可能很昂贵,因为它们依赖于浏览器来确定元素是否实际显示在页面上。在最坏的情况下,这可能需要完全重新计算 CSS 样式和页面布局!虽然我们不反对在大多数情况下使用它们,但我们建议您测试您的页面以确定这些选择器是否会导致性能问题。

此更改实际上已包含在 1.12/2.2 中,但我们想针对 jQuery 3.0 重申一下。

https://github.com/jquery/jquery/issues/2042

如上所述,升级指南 现已供所有准备好试用此版本的开发人员使用。除了对升级有所帮助外,它还列出了更多值得注意的更改。

关于“jQuery 3.0 版本候选…发布!”的 18 个想法

  1. 我会立即订阅您的 RSS,因为我找不到
    您的电子邮件订阅链接或电子邮件通讯服务。
    您有吗?请告诉我,这样我就可以订阅了。
    谢谢。

  2. 有没有人有时间用完全不熟悉 deferred 的人能理解的术语来解释 Deferred 示例,并使用您可能实际遇到的示例场景?我真心想理解它,但我没有理解。

  3. @Dave 困难可能来自在一个示例中展示所有三个更改,也许逐个理解会更容易。请加入 #jquery IRC 频道并 ping m_gol,我会尽量抽出时间解释。

  4. @Sebastian 我们正在考虑这个问题,并且很可能会在未来从 AMD 切换到 ES6 模块。不过目前还没有具体的计划。

  5. Stephane Pericat 说:

    我不得不承认,$.Deferred 的实现并没有遵循 ES6 promises 标准

    catch() 绝对不是 then() 的别名……它们处理不同的场景……当调用 Promise.resolve() 时应该调用 then(),当调用 Promise.reject() 时应该调用 catch()……

    像往常一样,你们不能做任何标准的事情(你们什么时候才会修复 $.each(),以便将值作为第一个参数传递,而不是索引??)

  6. Timmy Willison 说:

    @“Stephane Pericat”

    首先,我们并没有声称遵循 ES6 Promise 规范。我们声称 .then 与 Promises/A+ 兼容,并且已通过 npm 上提供的 Promises/A+ 测试套件进行了全面测试。

    其次,我们并没有声称 .catch() 是 .then() 的别名。我们声称 .catch(fn) 是 .then(null, fn) 的别名,而且事实正是如此(http://www.ecma-international.org/ecma-262/6.0/#sec-promise.prototype.catch)。

    第三,你对 then/resolve 和 catch/reject 的描述并非我所想,但我可以说,ES6 和 Promises/A+ 都在 promise 解决时调用 resolve 处理程序,在 promise 拒绝时调用拒绝处理程序,Deferreds 也同样如此。

    最后,不,我们不会更改 $.each 的参数顺序。$.each 的使用范围太广,无法做出如此重大的更改。此外,请记住,$.each 在成为标准之前就已经存在了。它影响了标准,这是一件好事。

    如果还有其他不清楚的地方,请随时在 #jquery irc 频道或 jQuery 论坛 (https://forum.jquery.com/) 中提问。

  7. Bemil Isat 说:

    如何鼓励设置/删除 .hidden CSS 类并检查它,而不是使用 .hide()/.show() 和可怕的 :visible 选择器?

  8. 如何鼓励设置/删除 .hidden CSS 类并检查它,而不是使用 .hide()/.show() 和可怕的 :visible 选择器?目前是否有计划尽快发布一个相应的 jQuery UI 版本来解决