jQuery 核心:版本 1.9 及以后

发布于 作者:

请查看 后续文章,再做决定,以免得出错误的结论。

正如上一篇博文讨论的那样,jQuery 版本 1.8 正在进行一次大扫除,以移除不安全、效率低下、无效且不建议使用的功能。我们还开始着手允许您构建自定义版本,排除库的某些部分,以获得更大的节省。这些努力将使您能够享受所需的 jQuery API,而无需携带您不需要的部分。

现在我们已经清理干净,是时候展望未来了。只有一个东西阻碍着我们对未来的愿景,那就是过去浏览器的幽灵。Internet Explorer 6、7 和 8——统称为 oldIE——一直是网络开发者十年来的一个痛点。 总体而言,这些来自过去时代的浏览器仍然代表着某些网站访问用户总数的三分之一。这数量很多——仍然希望获得网站提供的的信息、服务和产品的用户。对于许多使用 jQuery 的网站来说,忽略这些受众既不切实际也不有利可图。

jQuery 的设计初衷就是为了解决浏览器之间的差异,因此我们不会放弃我们理念的本质,简单地无视数百万仍然使用 oldIE 的活跃互联网用户(无论出于何种原因)。 然而,我们也希望前进,并利用现代浏览器,特别是不断增长的移动市场。

前进之路

jQuery 1.8 应该在一个月内发布。以下是我们对 jQuery 后续两个版本的思考,以及它们将发布的日期

  • jQuery 1.9(2013年初): 我们将移除版本 1.8 中已经弃用的许多接口;其中一些将作为插件或 jQuery 项目支持的替代 API 提供。IE 6/7/8 的支持将与今天一样。
  • jQuery 1.9.x(2013年及以后持续更新): 此版本将继续修复任何回归错误、新的浏览器错误等。
  • jQuery 2.0(2013年初,紧随 1.9 之后): 此版本将支持与 jQuery 1.9 相同的 API,但将移除对 IE 6/7/8 奇特的兼容性支持,例如损坏的事件模型、IE7“attroperties”、HTML5 补丁等。

我们的目标是让 1.9 和 2.0 在它们支持的 API 集方面可以互换使用。当 2.0 发布时,您选择哪个版本应该像这样简单:如果您需要 IE 6/7/8 的支持,请选择 1.9;否则,您可以使用 1.9 或 2.0。

问答

如果 jQuery 1.9 和 2.0 基本上是相同的 API,那么 2.0 有什么吸引力? 更小的尺寸、更好的性能以及摆脱了对 oldIE 支持的需求带来的问题。例如,我们预计可以在 2.0 中改进 $.Deferred 实现的错误处理,而只要支持 oldIE,我们就不可能做到这一点。

我的网站仍然有很多 IE7/8 访问者,但我希望使用 jQuery 2.0。我能做到吗? 如果您的网站需要 oldIE 支持,而且我们预计大多数网站至少在未来一两年内都需要它,您可以使用 IE 条件注释,仅在访问者使用 oldIE 时包含版本 1.9

<!--[if lt IE 9]>
    <script src="jquery-1.9.0.js"></script>
<![endif]-->
<!--[if gte IE 9]><!-->
    <script src="jquery-2.0.0.js"></script>
<!--<![endif]-->

为什么不为 jQuery 2.0 创建一个“oldIE 插件”? 对 oldIE 的特殊处理散布在 jQuery 的各个角落。重构代码以提供足够的钩子,以便可以将 oldIE 支持作为插件添加,会使现代浏览器的情况下的代码变得复杂。此外,支持 oldIE 并使用公共 CDN 的开发者将需要包含两个文件(jQuery 2.0 和 oldIE 插件),而不是一个。

一旦 jQuery 2.0 发布,1.9 会发生什么? 与过去不同,我们将继续修复 1.9 中的错误(作为次要版本)。在对 1.8 和 1.9 进行大扫除之后,我们预计未来不会添加很多新的 API。相反,我们更喜欢在有意义的情况下通过与两个版本兼容的插件添加新功能。因此,在使用版本 1.9 时,不要觉得您被抛弃了。

jQuery 2.0 基本上是为移动设备设计的吗? 不。虽然 jQuery 2.0 非常适合 HTML 移动应用程序,包括使用 jQuery Mobile 编写的应用程序,但它不是仅针对 iOS 和 Android 的 Webkit 库。除了移动浏览器,2.0 还会支持(并经过测试!)现代桌面版本的 Internet Explorer、Opera、Firefox、Safari 和 Chrome。

jQuery 2.0 会小多少/快多少? 在完成或至少接近完成之前,我们无法知道。您可以相信,我们将会在 2.0 的发布日期临近时告诉您更多信息。更好的是,您可以在发布测试版时尝试一下,亲眼看看!

jQuery 1.8 Beta 1:看看即将到来(和离开!)的内容

发布于 作者:

各位 jQuery 用户,大家好!自从上次与您联系以来,已经有一段时间了,但我们并没有睡觉。jQuery 核心团队一直在埋头苦干地开发 jQuery 1.8,我们的第一个测试版现在已经可用!您可以从 jQuery CDN 获取代码

在您当前的 jQuery 代码上试用一下,并告诉我们您的使用情况。如果您遇到问题,请 提交错误报告,包括一个测试用例,并确保说明您正在测试 jQuery 1.8 Beta 1。

在月底在旧金山举行的 jQuery 会议上,您将看到更多令人兴奋的 jQuery 新闻,之后将有博文跟进。

jQuery 现在为互联网上大约一半的主要网站提供支持;这是一个巨大的成功,但我们并没有停滞不前。在过去的六年里,Web 浏览器和它们运行的设备发生了令人难以置信的转变。Web 开发过程正在不断发展,以适应正在发生的变化。作为回应,jQuery 也在不断发展。

这种演变的一部分不仅仅是知道要添加什么,还要知道要删除什么。jQuery 的插件架构使开发者能够扩展 jQuery 核心提供的功能,只要这符合他们自己的需求。因此,对核心的添加的门槛已经设置得很高。我们不想为不需要特定功能的人创建大小、复杂性或性能损失。

同样,我们有足够的经验来了解一些最初看起来是个好主意的特性,最终却不是一个好主意。我们不想永远携带这些东西。事实上,我们希望更容易创建一个排除您不需要或不想要的东西的 jQuery 版本,尤其是在空间宝贵的移动环境中。

考虑到这一点,以下是我们为 jQuery 1.8 计划的一些更改,这将使其成为所有基于 HTML 的网页和应用程序的更好的基础,无论其平台如何

模块化

从 jQuery 1.8 开始,您可以构建一个自定义版本的 jQuery,排除一个或多个模块,如果您不需要它们的功能。我们的新构建系统基于 Ben Alman 令人惊叹的 grunt 工具,使这变得容易。要构建您自己的自定义版本,请设置 GitHub 上的 jQuery 核心仓库的副本,并使用 grunt 命令行选项排除模块。有关更多信息,请参阅 README 文件

您当前可以排除的模块是 ajax、css、dimensions、effects 和 offset。例如,如果您的应用程序完全使用样式表和 CSS 动画通过类来控制页面上项目的可见性和大小,您可以构建一个没有 css、dimensions、effects 和 offset 模块的版本。如果您不需要任何可选模块,您的自定义 jQuery 构建将是大约 21KB 的压缩和 gzip 格式。

但请不要担心,构建您自己的 jQuery 是完全可选的。jQuery 一直以来,并将继续以压缩和未压缩的形式分发为单个文件,并且可在 CDN 上使用。我们仍然期望大多数 jQuery 开发者会这样做,因为它简单且无痛。例如,当您包含您没有编写的 jQuery 插件时,使用完整的 jQuery 可以确保您不会被插件内部潜藏的依赖项所困扰。

供应商前缀的 CSS 属性

W3C 在提出使用供应商前缀作为尚未标准化的 CSS 功能时,心怀善意,但它并没有带来一个童话般的结局。Web 开发者面临着包含所有供应商前缀属性名称的样式的噩梦。jQuery 1.8 减轻了这种痛苦。我们自动获取非前缀属性名称并生成当前浏览器的适当前缀,因此您不必这样做。例如,在 Chrome 上,jQuery 调用 $("#myscroll").css("marquee-direction", "backwards") 将设置 CSS 为 -webkit-marquee-direction: backwards

动画(效果)

过去几年,我们的动画代码变得越来越混乱,我们希望在 1.8 版本中控制住这个局面。但这不仅仅是清理工作,还有几个扩展点,可以更轻松地添加或修改动画。目前,只有 初步文档 介绍了这些新功能,但在第一个 beta 版本中,我们的主要重点将是确保所有现有的动画代码都能正常工作。

如今,浏览器在提供高效动画方面做得越来越好,尤其是在使用 CSS 过渡时。但仍然有许多用户没有能够执行基于 CSS 动画的浏览器。使用 jQuery 1.8,您可以兼得两者。如果您需要支持没有内置动画的旧版浏览器,新的 $.Animation 提供了一个坚实的基础,并修复了先前版本中的许多错误。如果您只需要针对支持原生动画的现代浏览器,您可以这样做,并完全排除动画模块。

Sizzle CSS 选择器引擎

jQuery 的选择器引擎在 1.8 版本中进行了重大重写。这次重写最显著的好处是选择器匹配的广泛 性能提升,以及对最常用选择器的改进快捷方式。

此外,Sizzle 处理了更多边缘情况和错误,包括对多个组合器 (~ > +) 的改进支持,以及对 querySelectorAll 中浏览器错误的更好检测。有关完整列表,请参阅选择器模块下方的错误列表。

XSS 保护

设计上,$() 方法可以创建 HTML 元素,如果传递了带有内联脚本或 src 属性的 <script> 标签,则会运行脚本。开发人员有时会忘记这一点,将来自不受信任来源(例如 URL 或用户输入)的字符串传递给 jQuery。在这种情况下,有人可能会将脚本注入到页面中,从而窃取 cookie 或以某种方式破坏页面。

这些跨站脚本攻击 (XSS) 在许多网站上都很常见,无论是否使用 jQuery,但我们希望确保 jQuery 不会助长这个问题。在 jQuery 1.9(紧随 1.8 之后的下一个版本)中,我们将收紧 $() 方法的“看起来像 HTML”规则。只有当第一个字符是小于号时,字符串才会被视为 HTML,否则将被假定为 CSS 选择器。

作为进一步防止意外注入脚本的保护措施,jQuery 1.8 引入了一种新方法:$.parseHTML。它允许您将字符串指定为 HTML,并知道它们将被解析为 HTML,这是 $() 无法做到的,因为它还会将字符串解释为选择器。它还提供了一种将 HTML 解析为 DOM 片段并控制 HTML 中可能包含的任何脚本的执行的方法。这在由 内容安全策略 (CSP) 控制的 JavaScript 环境中尤其重要,因为注入的脚本可能会导致安全警告或异常。

对于创建单个元素(例如 $("<p/>"))的简单情况,以及特别是对于从外部数据构建字符串的情况,我们强烈建议使用 $.parseHTML。从 jQuery 1.9 开始,由于这些更严格的规则,某些 HTML 字符串将不再被 $() 识别。

大扫除

在 jQuery 1.8 中,我们还将弃用和删除“绊脚石”:效率低下、无效或不建议使用的 API 和功能。我们意识到仍然存在需要这些功能的 jQuery 代码。为了提供一个轻松的未来升级路径,我们将许多已弃用的项目在删除后提供兼容性插件。您可以在其 GitHub 仓库 中关注兼容性插件的开发。

以下票证(以“弃用”或“删除”开头)讲述了所有更改的内容,但以下是一些特别值得注意的更改

$.browser: 自 jQuery 1.4 以来,我们一直在宣传通过用户代理字符串进行浏览器检测是一个坏主意。但我们通过继续提供 $.browser 助长了不良实践。从 jQuery 1.9 开始,我们将完全删除它,您需要使用 1.9 兼容插件。如果您的代码尚未放弃浏览器检测,请查看 Modernizr,它提供了一套非常全面的功能检测,您可以用来代替。当然,您也可以直接阅读 navigator.userAgent 字符串,没有什么可以阻止您,除了您的良心。

$.sub: 此方法是在 jQuery 1.5 中引入的,但它并未证明对核心有用或足够健壮。它将在 jQuery 1.9 中移动到兼容性插件。

全局 ajax 事件: 当前,由 $.ajax 触发的事件(例如 ajaxStart)可以附加到任何元素,甚至附加到根本不在文档中的元素!这会创建一个效率低下的特殊情况,因此我们将在 1.8 中弃用此行为。从 1.9 开始,ajax 事件应仅附加到 document

还有更多…

1.8 中还有许多其他更改,也许查看我们一直在做的事情的最简单方法是查看正在修复的问题列表,其中包括功能和错误修复。以下是今天 1.8 的快照,但它并非一成不变。我们欢迎您对特定问题或 jQuery 的整体方向的反馈!

jQuery 1.8 Beta 1 更改日志

1.8 Beta 1 版本的当前更改日志。

Ajax

  • #8205: JSONP 随机结果导致 IE8 中出现内存泄漏
  • #8653: jQuery.param 在查询字符串中输出“null”和“undefined”
  • #10285: evalScript rcleanScript 替换在 IE8 中失败
  • #10524: jQuery.fn.load 不会将 data 参数与 jQuery.ajaxSetup 合并
  • #10944: $.ajax 并不总是返回实现 Promise 接口的对象
  • #11013: 弃用/删除 $.ajax 中的 async 选项
  • #11402: evalScript 函数在 IE 中出现错误 80020101
  • #11743: jQuery 在 $.appendTo() 中对 script 标签 ajax 请求期间的错误保持沉默
  • #11778: 缓存的 XHR 请求仍应异步解析

属性

  • #11153: jQuery 1.7 在 IE 8 中剥离回车符
  • #11212: Sizzle.getText 在 IE 上将不可断行空格转换为空格

构建

  • #11767: 支持不带效果的自定义构建
  • #11789: 更新 README 以描述 grunt 构建系统
  • #11856: 模块化尺寸
  • #11857: 模块化 css
  • #11865: 模块化偏移

核心

  • #10657: 弃用 jQuery#size() 以支持 jQuery#length
  • #11290: 选择器被解释为 HTML
  • #11470: 添加内置的 readyP promise

Css

  • #10373: `document.defaultView` => `window`
  • #10413: width、innerWidth、innerHeight、outerWidth、outerHeight 对于 box-sizing: border-box 的隐藏父元素的子元素不准确
  • #10679: CSS3 供应商前缀支持
  • #11004: getWH 在 box-sizing 为 border-box 时错误地删除了填充和边框宽度
  • #11787: 删除 jQuery.curCSS

数据

  • #10589: 删除 $.fn.data("events")

Deferred

  • #11010: 使 Deferred.then == Deferred.pipe 类似于 Promise/A
  • #11011: 允许 $.Callbacks 标志的传统选项对象
  • #11736: 删除 Deferred .isResolved() 和 .isRejected()
  • #11749: 在 $.when() 中传递多个 Deferred 对象时保留上下文对象

Dimensions

  • #6724: 在移动 Safari (iPhone) 中 $(window).height() 错误
  • #10877: 使 outerWidth/Height 成为 setter
  • #11293: 读取空 TD 的宽度或 outerWidth 会改变列的宽度值
  • #11604: 将 $(elem).width(-val) 从无操作更改为 $(elem).width(0)
  • #11724: Firefox 12 中 $(document).height() 已更改

Effects

  • #7109: animate width 在 WebKit 中以无效宽度开始
  • #7157: 动画回调显示元素仍然为“:animated”
  • #8387: 使用 WebKit 中的内联和内联块元素时,hide/show 问题导致闪烁
  • #8627: .animate() 在 IE 中对 letterSpacing 失败(1.5.1 中的回归)
  • #8892: 在 clone() 之后调用 appendTo() 和类似方法返回错误的 jQuery 集合
  • #9505: 在 WebKit 中混合百分比和像素时出现 animate() 问题
  • #11635: 动画期间显式 overflow:auto 被内联 overflow:hidden 覆盖
  • #11755: animate 及其别名不应使用 :hidden 选择器
  • #11854: 百分比动画跳转到结束

事件

  • #8545: IE 中存在泄漏事件
  • #10067: 在 document.readyState === 'interactive' 时触发 $.ready
  • #11101: 弃用 trigger 方法中的“exclusive”事件选项
  • #11328: 在 Windows 上 Ctrl 键不会将 event.metaKey 设置为 true
  • #11500: 错误:手动触发 IE7 和 IE8 中的“change”事件处理程序未执行
  • #11621: 在 document 上触发事件不会冒泡到 window
  • #11718: 弃用 .data() 事件
  • #11719: 弃用 .bind("ready") 事件
  • #11731: 弃用“hover”伪事件
  • #11733: 弃用 .load()、.unload() 和 .error() 方法
  • #11786: 弃用 .toggle( handler, handler, … ) 签名

操作

  • #8894: 在 clone() 之后调用 appendTo() 和类似方法返回错误的 jQuery 集合
  • #10324: Clone 不会复制 object 元素的 innerHTML
  • #11231:Append、Prepend、After、Before 方法应接受数组作为第一个参数
  • #11338:.replaceWith() 和断开连接的节点行为不一致。
  • #11566:node.append 等方法在节点是 DocumentFragment 时不起作用
  • #11617:定义一个 $.parseHTML 方法用于创建 HTML 片段

Offset

  • #10996:简化 offset()
  • #11823:移除 webkitConvertPointFromNodeToPage

选择器

  • #3778:选择器匹配问题
  • #5568:在 FF/IE 上,选择器对带有注释标签的行为不同
  • #8473:在 IE9rc 中,*[tabIndex] 会选择所有没有 tabindex 属性的元素
  • #9400:弃用 :text、:radio、:checkbox 等选择器扩展
  • #10003:#6963 引入的回归/BC 破坏
  • #10074:链式调用两个 [] 选择器并使用 :first 不起作用
  • #10570:当页面上有跨域 iframe 时,:text 选择器在 IE7 中会抛出错误
  • #10697:Sizzle 重构
  • #10809::focus 伪类解析器中不正确的测试使用了“.activeElement”
  • #11109:Sizzle: Expr.relative 过早截断
  • #11814:Sizzle 的基于元素的 QSA 策略(即附加一个临时 ID)没有考虑到逗号和其他选择器分隔符
  • #11826:探索 Sizzle 中 matchesSelector 的解析缓存系统

支持

  • #9385:弃用 jQuery.browser
  • #11439:jQuery.support.parentNode 已使用,但不再定义。
  • #11721:弃用并移除 jQuery.support.boxModel 的内部使用
  • #11766:将 jQuery.support 移动到“不稳定”状态

Traversing

  • #9800:新方法:.addBack(取代 .andSelf)
  • #11543:.has 在分离的元素上不起作用
  • #11706:`.has()` 在文档片段上失败
  • #11738:移除 .closest(Array) 返回 Array

未归档

  • #11325:改进 domManip/buildFragment/clean
  • #11435:过时的测试代码,移除 .data 的返回值中的 toJSON
  • #11777:添加 jQuery Core 对 EditorConfig 文件的支持