【译】jQuery 3.0 以及兼容版的 Alpha 版本发布
发布在不顾一切地在平坦的路面上曲折前行2016年2月26日view:2333前端开发jQuery
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

It’s been a long time since we did a major release, and you certainly deserve one. So we’re glad to announce the first alpha of jQuery 3.0!

从我们做出上一个重大的版本发布已经过去很长时间了,所以你理应再得到一个新版本。因此我们非常高兴的宣布 jQuery 3.0 的第一个 alpha 版本的发布。

Despite the 3.0 version number, we anticipate that these releases shouldn’t be too much trouble when it comes to upgrading existing code. Yes, there are a few breaking changes that justified the major version bump, but we’re hopeful these breakages don’t actually affect that many people. The jQuery Migrate plugin can help you to identify compatibility issues in your code as well. Your feedback on the changes in this alpha will help us greatly, so please try it out on your existing code and plugins!

尽管版本号已经到了 3.0,但是在升级目前已经存在的代码时,可以预期这些发布不会造成太多的麻烦。确实,只是一些用来调整重要版本冲突的零碎改变,但是我们希望这些改变不会实际影响到很多人。jQuery Migrate 插件可以很好的帮助你在你的代码中识别出兼容性问题。在这个 alpha 版本中,你针对于这些变化的反馈将会极大的帮助我们,所以请在你目前已有的代码和插件中尝试一下。

There are actually two releases here. First is jQuery 3.0, which supports modern browsers and environments from IE9 forward. Second is jQuery Compat 3.0, which includes support for IE8. As an added bonus, both jQuery and jQuery Compat will include support for Yandex.Browser, a freeware browser released in 2012. You can get the files from the jQuery CDN, or link to them directly:

实际上,这里有两个版本。第一个版本是 jQuery 3.0, 这个版本支持现代浏览器和 IE9 以后的浏览器环境。第二个版本是 jQuery Compat 3.0,这个支持 IE8。作为一个额外的福利,就是 jQueryjQuery Compat 这两个版本都支持 Yandex 浏览器(一个2012年发布的免费软件)。你可以从 jQuery CDN 或者直接通过下面这些链接获取这两个文件。

https://code.jquery.com/jquery-3.0.0-alpha1.js

https://code.jquery.com/jquery-compat-3.0.0-alpha1.js

You can also get the alpha versions from npm:

你也可以从 npm 中获取 alpha 版:

npm install jquery@3.0.0-alpha1

npm install jquery-compat@3.0.0-alpha1

Major changes (主要的变化)

Below are just the highlights of the major new features, improvements, and bug fixes in these releases. A complete list of changes is available at the bottom of this post and on our GitHub issue tracker. On GitHub, you can additionally see the features we expect to put in later beta and final versions that have yet to land.

下面的这些内容只是高亮了这个版本中一些重要的新特性,代码的改进,还有一些 bug 的修复。在这篇文章下面和我们的 GitHub issue tracker 板块你可以看到一个完整的改变清单。在 Github 上,你还可以看到我们期待在下个 beta 版本和暂时还没发布的最终版中添加的新特性。

Simplified .show() and .hide() methods: 简化的 show 和 hide 方法

Everyone’s mental model of jQuery’s .hide() method is that it sets display: none in CSS. Conversely, .show() clears the display so that the element shows again (assuming its parents are not hidden). Simple, right?

每个人的心中都认为 jQuery 中的 .hide() 方法就是把元素设置为 display:none,相反的,.show() 方法就是清除 display 因此元素会重新显示(假设父级元素没有被隐藏)。很简单,对么?

Well, no. There are actually many complex special cases that people asked us to “fix” over the years, which turned these methods into a convoluted confluence of principles. For example, what if the element is set to display: none in a stylesheet? jQuery would try to override that by forcing display: block on the element directly. Okay, but what if a normally block element like

  • was set to display: inline by a different stylesheet rule? How about the case where you call these methods on an element before it’s been added to the document and we don’t know what display value it will have? Determining all of that takes extra work. Sometimes it’s still just a guess that turns out to be wrong.

    不,这么多年来,实际上有很多复杂特殊的例子,人们要求我们去修正一下,这些例子使得这些方法陷入一个复杂的原理集合之中。例如,如果一个元素在样式表中设置为 display: none 将会怎样?jQuery 会试着在元素上强制设置 display: block 去覆盖它。这是可以的。但是像 <li> 这样的一个正常的块元素通过不同的样式规则被设置为 display: inline 会怎么样呢?在一个元素被添加到 document 之前你调用了这个方法并且我们不知道这个元素拥有的 display 值的话又会怎样?确定这些事情需要花费额外的工作。有时仅仅是一个最后被证明是错误的猜想。

    Since these methods add a style attribute to the element, they don’t tend to play well with techniques like responsive design where the visibility of elements may also be set by media queries. This leads to the need for jQuery handlers that listen for the orientationchange or resize events and manually hide or show parts of the page; it defeats the elegant solution that media queries were trying to implement.

    这些方法在元素上添加一个样式属性之后,在像是响应式设计中(元素的可见性需要通过媒体查询来设置)这样的技术上往往不能很好的表现。这个导致需要 jQuery 处理器去监听 orientationchangeresize 事件人工隐藏或显示部分页面;jQuery 打败了媒体查询正尝试实现的优雅的解决方案。

    You can see that jQuery was already about halfway down the path to total madness, and it didn’t make sense to complete the journey. The special cases and checks were not only complex and incomplete, but they caused significant performance issues on large pages.

    你可以看到 jQuery 已经完成了疯狂旅途中的一半路程了,但是完成整个旅程是行不通的。这个特殊的情况以及检查不仅复杂且难以完成,而且在大的页面中会造成具有重大意义的性能问题。

    So, instead, we’re experimentally defying the evolution of these methods and reverting to a simple, primordial model. This will break some code. If you have elements in a stylesheet that are set to display: none, the .show() method will no longer override that. So the most important rule for moving to jQuery 3.0 is this: Don’t use a stylesheet to set the default of display: none and then try to use .show() – or any method that shows elements, such as .slideDown() and .fadeIn() – to make it visible.

    因此,代替的是,我们实验性的反抗这些方法的演变,重新回归到一个简洁的,原始的模型。这将会分解一些代码。如果一个元素在样式表中被设置为 display: none.show() 方法将不会再覆盖它。因此,转移到 jQuery 3.0 中有一个最重要的规则就是: 不要使用样式去设置 display: none 作为默认值,然后使用 .show() 或者其他方法来显示元素,例如使用 .slideDown().fadeIn() 方法来使它可见。

    If you need an element to be hidden by default, the best way is to add a class name like “hidden” to the element and define that class to be display: none in a stylesheet. Then you can add or remove that class using jQuery’s .addClass() and .removeClass() methods to control visibility. Alternately, you can have a .ready() handler call .hide() on the elements before they are displayed on the page. Or, if you really must retain the stylesheet default, you can use .css(”display”, “block”) (or the appropriate display value) to override the stylesheet.

    如果你需要让一个元素默认是隐藏状态,最好的方法是给元素添加一个像 hidden 这样的类名,然后在样式中去定义这个类为 display: none,然后你可以使用 jQuery.addClass().removeClass() 方法来添加或删除这个类来控制其可见性。另外一种方法是,你可以在元素显示到页面中之前,使用 .ready() 处理器并在其中调用 .hide() 方法。或者,如果你一定要在样式中保留默认值,你可以使用 .css("display", "block") (或其他合适的值)去覆盖样式。

    We know that this is likely to be one of the most contentious and difficult changes in jQuery 3.0, so we wanted to put it out in this early release to see the effects. Please let us know how it affects your code and what you need to change in order to work with this new model.

    我们知道这可能是 jQuery 3.0 中最受争议和最困难的改变,所以我们想把它放到这个早期版本中观察一下所造成的影响。请让我们知道这些改变如何影响了你的代码,以及你为了使用这个新版本所作出的改变。

    https://github.com/jquery/jquery/issues/1767 https://github.com/jquery/jquery/issues/2057 https://github.com/jquery/jquery/issues/2308

    Special case with .data() names: 含有.data()名字的特殊事例

    We have updated our .data() implementation to closer match the HTML5 dataset specification. All keys are now converted from kebab-case to camelCase, regardless of access method, and digits no longer participate in the conversion. For example, we will no longer differentiate between “foo-bar” and “fooBar”, but will differentiate between “foo-42” and “foo42”. These changes will mainly come into play when retrieving all data by calling .data() with no arguments, or when trying to access the data using a converted key (.data(“foo42”)) instead of the original (.data(“foo-42”)).

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

    我们也更新了我们的 .data() 方法来更有效的匹配 HTML5 dataset specification. 所有的键值现在都从 kebab-case 转换成驼峰命名法,不再理会访问方式,数字也不再参与转换。例如: 我们不再区分 foo-barfooBar,但是仍然区分 foo-42foo42。当通过调用无参数的 .data() 来取得所有的数据方法,或者尝试通过转换的键名(.data(“foo42”))而不是原始的(.data(“foo-42”))来获取数据时,这些改变将会发挥主要作用。

    jQuery.Deferred is now Promises/A+ compatible: jQuery.Deferred现在兼容Promises/A+

    jQuery.Deferred objects have been updated for compatibility with Promises/A+ and ES2015 Promises, verified with the Promises/A+ Compliance Test Suite. This meant the introduction of a .catch() method and some major changes to the .then() method:

    jQuery.Deferred 对象为了兼容 Promises/A+ES2015 Promises 已经做出了更新,Promises/A+ Compliance Test Suite 检验。这意味着 引入一个 .catch() 方法,.then()方法也有一些重要的改变。

    • An exception thrown in a .then() callback now becomes a rejection value. Previously, exceptions bubbled all the way up, aborting callback execution and irreversibly locking both the parent and child Deferred objects.
    • .then() 方法的回调函数中抛出的异常现在变成了一个可注入的值。以前,异常会一直往上冒泡,直至终止回调函数的执行,然后不可撤销的锁定 parent and child Deferred 对象。
    • The resolution state of a Deferred created by .then() is now controlled by its callbacks—exceptions become rejection values and non-thenable returns become fulfillment values. Previously, returns from rejection handlers became rejection values.
    • 通过 .then() 方法创建的 Deferred 对象的 resolution 状态现在被它的回调函数控制——异常成为了注入值,并且 non-thenable 返回的结果成为了 fulfillment 值。以前,从注入处理器返回变成了注入值。
    • Callbacks are always invoked asynchronously. Previously, they would be called immediately upon binding or resolution, whichever came last.
    • 回调函数总是被异步调用。以前,它们根据绑定或是 resolution 被立即调用,无论哪个更晚一些。
    • Progress callbacks can no longer resolve Deferred objects to which they are bound.
    • Progress 回调函数不再解决受约束的 Deferred 对象。

    Consider the following, in which a parent Deferred is rejected and a child callback generates an exception:

    考虑一下下面的代码,哪个parent Deferred 被注入以及 child 回调函数产生异常:

    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" );

    As of jQuery 3.0, this will log “parent resolved” before invoking any callback, each child callback will then log “fulfilled bar”, and the grandchildren will be rejected with Error “baz”. In previous versions, this would log “rejected bar” (the child Deferred having been rejected instead of fulfilled) once and then immediately terminate with uncaught Error “baz” (“parent resolved” not being logged and the grandchildren remaining unresolved).

    在 jQuery 3.0 中,在调用任何回调之前会先记录 “parent resolved”,每一个子回调将会记录 “fulfilled bar”, 然后 grandchildren 将会和错误 “baz” 一起注入。在之前的版本中,会记录一次 “rejected bar” (child Deferred 已经注入而不是fulfilled)然后通过未捕获到的错误 “baz” 中断(“parent resolved” 不会被记录并且 grandchildren 会保持 unresolved 状态)。

    While caught exceptions had advantages for in-browser debugging, it is far more declarative (i.e. explicit) to handle them with rejection callbacks. Keep in mind that this places the responsibility on you to always add at least one rejection callback when working with promises. Otherwise, any errors will go unnoticed.

    当捕获异常时有利于在浏览器中进行 debug, 使用注入回调来处理异常非常具有描述性(即显式的)。记住这个地方,你有责任在使用 promises 时总是添加至少一个注入回调,否则,任何错误都不会提示。

    Legacy behavior can be recovered by replacing use of .then() with the now-deprecated .pipe() method (which has an identical signature).

    Legacy 行为可以通过使用现在还不宜用的 .pipe() 方法替换 .then() 方法来重新获取,

    jQuery.when has also been updated to accept any thenable object, which includes native Promise objects.

    jQuery.when 方法也为了接受任何 thenable 对象而更新了,包括了原生的Promise对象。

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

    Removed special-case Deferred methods in jQuery.ajax: 移除了jQuery.ajax中Deferred方法的一些特殊情况

    jqXHR object is a Promise, but also has extra methods like .abort() so that you can stop a request after it has been made.

    jqXHR 对象是一个Promise,但是也有像 .abort() 这样的额外的方法。因此你可以在创建之后停止一个请求。

    As users increasingly embrace the Promise pattern for asynchronous work like AJAX, the idea of having special cases for the Promise returned by jQuery.ajax is an increasingly bad idea.

    随着用户越来越拥护类似像 AJAX 这样异步执行的 Promise 模式,通过 jQuery.ajax 进行 Promise 返回特殊事例的想法是越来越坏的主意。

    success, error, complete done, fail, always

    Note that this does not have any impact at all on the callbacks of the same name, which continue to exist and are not deprecated. This only affects the Promise methods!

    注意,这些对于相同名字的回调函数没有任何影响,它们将会继续存在,而且不会被弃用。这个只会影响Promise 方法!

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

    Error cases don’t silently fail: 错误事例不会默默地失败

    Perhaps in a profound moment you’ve wondered, “What is the offset of a window?” Then you probably realized that is a crazy question – how can a window even have an offset?

    也许在一个重要的时刻你会想知道,“窗口的偏移量是多少?” 然后你可能会意识到这是一个疯狂的问题 - 窗口怎么会有偏移量?

    In the past, jQuery has sometimes tried to make cases like this return something rather than having them throw errors. In this particular case of asking for the offset of a window, the answer up to now has been { top: 0, left: 0 } With this alpha of jQuery 3.0 we’re experimenting with the idea of having such cases throw errors so that crazy requests aren’t silently ignored. Please try the alpha and see if there is any code out there depending on jQuery to mask problems with invalid inputs.

    在过去,jQuery 有时会尝试去创建类似返回一些东西的事例而不是抛出一个错误。在这个询问窗口的偏移量的特殊事例中,到目前为止答案已经变成了 { top: 0, left: 0 },在 jQuery 3.0alpha 版本中,我们正在尝试抛出一个错误来让这些疯狂的请求不至于被默默地忽略掉这样的想法。请尝试使用 alpha 版本看一下是否存在一些依赖 jQuery 的代码出现无效输入的问题。

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

    .width(), .height(), .css(“width”), and .css(“height”) to return decimal values (whenever the browser does)

    .width(), .height(), .css(“width”), 和 .css(“height”) 方法将返回带有小数点的数值(不论何时浏览器都会这样做)。

    Previously, jQuery rounded values when retrieving width and height. Some browsers return subpixel values – such as IE and Firefox – and sometimes users need this precision when relying on these values for layout. We don’t expect this change to have a big impact on your code, but let us know if it does.

    以前,当你获取 width 和 height 的时候 jQuery 会对其进行取整。有一些浏览器会返回亚像素值 - 例如 IE 和 Firefox,并且有时当布局依赖这些值时用户需要这种精确度的值。我们不希望这些改变会对你的代码产生很大的影响,但是如果确实影响到了,请让我们知道。

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

    Removed deprecated event aliases: 移除不赞成使用的事件别名

    .load, .unload, and .error, deprecated since jQuery 1.8, are no more. Use .on() to register listeners.

    .load, .unload, 和 .error, 这些方法自从 jQuery 1.8 就已经弃用,而且永不使用。使用 .on() 注册监听器

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

    jQuery.swap, jQuery.buildFragment, and jQuery.domManip are no longer accessible on the jQuery object

    jQuery.swap, jQuery.buildFragment, 和 jQuery.domManip 不再从 jQuery 对象上获取。

    These methods were always intended for internal use only and were never documented. We are finally making them private to avoid confusion.

    这些方法常常仅在内部使用,而且也从来没有文档说明。为了避免疑惑,我们最终决定将他们私有化。

    https://github.com/jquery/jquery/issues/2224 https://github.com/jquery/jquery/issues/2225

    Animations now use requestAnimationFrame:动画现在使用requestAnimationFrame

    On platforms that support the requestAnimationFrame API, which is pretty much everywhere but IE8 and IE9, jQuery will now use that API when performing animations. This should result in animations that are smoother and use less CPU time – and save battery as well on mobile devices.

    除了 IE8IE9 之外,越来越多的平台都支持 requestAnimationFrame API,jQuery 现在在执行动画的时候也使用了此 API。这样的结果是会让动画越来平滑流畅,并且使用更少的 CPU 时间,在移动设备上也尽可能好的保存电量。

    jQuery tried using requestAnimationFrame a few years back but there were serious compatibility issues with existing code so we had to back it out. We think we’ve beaten most of those issues by suspending animations while a browser tab is out of view. Still, any code that depends on animations to always run in nearly real-time is making an unrealistic assumption.

    jQuery 尝试使用 requestAnimationFrame 了一些年头,但是在目前的代码中有一些很严重的兼容性问题,因此我们又把它撤销回去了。我们认为我们通过当浏览器标签页移出视野时暂停动画这种方式已经解决了这些问题中的大多数。然而,在真实的运行时环境中,任何依赖于动画的代码一直运行是一个不切实际的假想。

    .unwrap( selector )

    Before jQuery 3.0, the .unwrap() method did not take any arguments. The selector parameter offers a way to be specific about which wrappers to remove.

    jQuery 3.0 之前,.unwrap() 方法不接收任何参数。selector 参数提供了一个确定哪个包装器该被移出的方式。

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

    Massive speedups for some jQuery custom selectors

    Thanks to some detective work by Paul Irish at Google, we identified some cases where we could skip a bunch of extra work when custom selectors like :visible are used many times in the same document. That particular case is up to 17 times faster now!

    感谢来自 Google 的 Paul Irish 所做出的一些排查工作,我们才可以识别出我们可以跳过的一些额外工作,像是 :visible 这样的常规的选择器在一个文档中使用好多次。特定的事例中现在在性能上能比以前快 17 倍。

    Keep in mind that even with this improvement, selectors like :visible and :hidden can be expensive because they depend on the browser to determine whether elements are actually displaying on the page. That may require, in the worst case, a complete recalculation of CSS styles and page layout! While we don’t discourage their use in most cases, we recommend testing your pages to determine if these selectors are causing performance issues.

    记住,即使这些事情改善了,像是 :visible:hidden 这样的选择器也是很昂贵的,因为它们依赖于浏览器来决定什么时候元素确实显示在页面上。可能需要的是,在最差的情况中,CSS 样式和页面布局需要完整的重绘。尽管在大多数情况下我们不阻止使用他们,但是我们推荐你在你的页面上测试一下来确定这些选择器是否会造成一些性能问题。

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

    译者注:

    具体的更新内容列表没有在此翻译,如果想具体了解请自行查看英文原文。

    本文根据 Timmy Willison 的《jQuery 3.0 and jQuery Compat 3.0 Alpha Versions Released》所译,整个译文带有自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://blog.jquery.com/2015/07/13/jquery-3-0-and-jquery-compat-3-0-alpha-versions-released/

    相关链接

    PS: 文章首发在我的博客,原文链接为http://blog.sqrtthree.com/2015/11/12/jQuery3-0-Alpha-Versions-Released/

  • 评论
    发表评论
    4年前
    赞了此文章!
    WRITTEN BY
    根号三
    http://blog.sqrtthree.com/
    TA的新浪微博
    PUBLISHED IN
    不顾一切地在平坦的路面上曲折前行

    不顾一切地在平坦的路面上曲折前行。

    我的收藏