jQuery Core 4.0 升级指南


[!注意] jQuery 4.0 尚未正式发布。这是 jQuery 4.0 升级指南的草案。jQuery 4.0 目前正在开发中,本指南将随变更的确定而更新。jQuery 团队欢迎对本指南及 jQuery 4.0 变更的反馈。

链接 概览

借 4.0 大版本发布之际,jQuery Core 团队清理了 API 并修复了可能对某些用户造成破坏性影响的错误。这包括移除此前已弃用的公开 API、更改或移除未公开的 API,以及针对特定输入更改现有 API 的公开或未公开行为。

链接 浏览器支持

自 jQuery 4.0 起,支持以下浏览器:

  • Internet Explorer: 仅限 11
  • Chrome, Edge, Firefox, Safari: 当前版本及前一个版本 (Current, Current - 1)
  • Opera: 当前版本
  • Safari Mobile iOS: 当前版本、前一个及前两个版本 (Current, Current - 1, Current - 2)
  • Android: 当前版本及前一个版本 (Current, Current - 1)

链接 不再支持的浏览器

  • Edge: 旧版 (非 Chromium) 版本
  • Internet Explorer: 10 及以下版本
  • Safari Mobile iOS: 所有早于 Current - 2 的版本
  • Android: 所有早于 Current - 1 的版本

浏览器支持在 jQuery 下一个大版本 (5.0) 之前不会改变。

链接 jQuery Migrate 插件

新版本的 jQuery Migrate 插件 已发布,用于简化旧代码向 4.0 版本的迁移。我们强烈建议您将此插件作为升级工具使用,它会针对可能影响您代码的大多数主要变更提供具体建议。

jQuery Migrate 插件 4.0 版本 不会 对 jQuery 1.0、2.0 或 3.0 等之前大版本变更中移除的行为进行提醒或恢复。请按照以下步骤从早于 1.11.0 或 2.1.0 的 jQuery 版本升级到新的 4.0 版本:

链接 如果当前使用 jQuery <1.9,请从此开始

  1. 将页面上的 jQuery 版本升级到最新的 1.x 或 2.x 版本。
  2. 在页面中添加未压缩的 jQuery Migrate 1.x 插件
  3. (可选但推荐) 升级正在使用的所有插件,因为后续版本通常与最新版 jQuery 的兼容性最好。
  4. 测试页面并解决控制台中出现的任何警告,参考 JQMIGRATE 1.x 警告文档 进行操作。
  5. 移除 jQuery Migrate 1.x 插件,确保页面上更新后的 jQuery 代码在仅使用最新 jQuery 1.x/2.x 的情况下仍能正常工作。

链接 如果当前使用 jQuery >=1.9,请从此开始

  1. 将页面上的 jQuery 版本升级到最新的 4.x 版本。
  2. 在页面中添加未压缩的 jQuery Migrate 3.6.0 插件。jQuery Migrate 4.x 同样适用(注意它仅支持与 jQuery 4.x 相同的浏览器),但目前尚未发布。
  3. (可选但推荐) 升级正在使用的所有插件,因为后续版本通常与最新版 jQuery 的兼容性最好。
  4. 测试页面并解决控制台中出现的任何警告,参考 JQMIGRATE 4.x 警告文档 进行操作。向插件作者报告第三方插件中的任何错误。

注意:一旦 jQuery 4.x 发布,jQuery Migrate 3.x 插件将进入维护模式,仅接收关键错误更新。本指南将相应更新以反映此变化。

不支持同时运行多个版本的 jQuery Migrate。

未压缩的开发版 Migrate 插件包含控制台日志输出,可在使用特定的已弃用和/或已移除功能时发出警告。这使其成为调试现有 jQuery 代码和插件、查找并修复问题的宝贵迁移工具。

压缩版的 Migrate 插件不会生成任何警告,但会发出一条单独的控制台消息表示其已加载。当需要使用 jQuery 3.0 或更高版本但仍需兼容旧版 jQuery 代码或插件时,可以在生产环境中使用 Migrate。理想情况下,这仅作为短期解决方案,因为恢复旧行为可能会与期望新行为的新 jQuery 代码产生冲突。

链接 重要变更摘要

对于像 jQuery 这样应用广泛的库,团队很难在发布前完全预知哪些变更对开发者的影响最大。尽管列表很长,但我们相信大部分属于极端情况。许多 jQuery 项目应该只需少量修改(甚至无需修改)即可运行 4.0 版本。

变更按组件类别列出,并附带描述前缀以帮助您了解其影响:

  • 重大变更 (Breaking change): 此变更可能影响现有代码,因为它以某种方式改变了 API 表面。大多数情况下,其影响仅限于注明的特定极端情况。
  • 功能 (Feature): 此变更为 API 增加,在大多数情况下不会影响现有代码。然而,新功能仍有可能与现有代码产生负面交互。
  • 已弃用 (Deprecated): 此功能或 API 在 jQuery 3.0 中仍存在,但不鼓励使用。它可能会在未来的主版本更新中移除。

请记住,上述 jQuery Migrate 插件可以检测并警告许多此类变更,以便在代码中进行修复。

有关所有代码变更的完整详细列表,请参阅 jQuery Core 问题追踪器 中的 4.0 里程碑,或查看 版本差异

链接 Ajax

链接 重大变更:移除 JSON 到 JSONP 的自动提升

此前,设置了回调的 jQuery.ajaxdataType: "json")会自动转换为 JSONP 请求,除非显式指定 jsonp: false。如今,与跨域后端交互的首选方式是 CORS,它在 jQuery 4 支持的所有浏览器中均可工作。

将 JSON 请求自动提升为 JSONP 会引入安全问题。开发者可能在不知情的情况下执行了来自远程域的代码。该自动提升逻辑现已禁用。

若要触发 JSONP 请求,现在必须明确指定 dataType: "jsonp"

链接 重大变更:若未指定 dataType: "script",脚本将不再自动执行

jQuery 3.0.0 已经停止对通过 jQuery.ajax 获取的跨域脚本进行自动执行,除非显式设置了 dataType: "script"。这一变更现已扩展至同域脚本。

若要获取执行脚本,请在 jQuery.ajax 选项中传递 dataType: "script" 或使用 jQuery.getScript

链接 重大变更:所有异步请求现在均使用 Script 标签

在 jQuery 4.0 之前,AJAX 脚本传输仅在跨域请求或设置了 scriptAttrs 时才使用 script 标签加载脚本。现在,我们对异步请求始终使用 script 标签,以避免任何 内容安全策略 (CSP) 错误。

如果某些脚本原先期望在设置了 CSP 标头的情况下仍能执行,此变更可能会影响现有代码。请修改 CSP 标头以允许来自同域的脚本,或移除这些脚本。

链接 潜在重大变更:jQuery.ajax 现在支持二进制数据

jQuery 4.0 通过支持将 FormData 对象传递给 data 参数,为 jQuery.ajax 请求添加了对二进制数据的支持。此变更可能会影响依赖于 jQuery.ajax 此前处理不可序列化数据类型行为的代码,尤其是依赖于 Ajax 预过滤器 (prefilter) 执行顺序的代码。以前,数据在应用预过滤器之前会被转换为字符串。尽管如此,我们预计此变更不会影响大多数用户。

链接 属性 (Attributes)

链接 重大变更:移除 toggleClass( Boolean | undefined ) 签名

这一特定签名在 jQuery 3.0 中已被弃用,现于 jQuery 4.0 中移除。经过社区反馈和讨论,我们确定该签名会导致意外行为。例如,如果 toggleClass 的参数是一个结果为 undefinedfalse 的变量,则会导致所有类名被移除。此外,虽然 toggleClass( boolean ) 签名是有文档记载的(且自 3.0 起标记为弃用),但 toggleClass( undefined ) 签名从未被记录。

迁移建议是:明确指定应切换哪些类名。

链接 核心 (Core)

链接 重大变更:移除已弃用的 API

以下 API 在之前的版本中已弃用,现已在 jQuery 4.0 中移除:

  • jQuery.camelCase:此函数从未公开记录且仅供内部使用。它在 jQuery 3.0 中被弃用。

  • jQuery.cssProps:此对象用于将 CSS 属性映射到其供应商前缀版本,在 jQuery 4.0 支持的浏览器中已不再需要。

  • jQuery.isArray:请使用 Array.isArray。

  • jQuery.isFunction:请使用 typeof value === "function"。

  • jQuery.isNumeric:请使用 Number.isFinite 或自定义实现。

  • jQuery.isWindow:窗口检测通常不可靠且不被推荐。如果绝对必要,请使用 obj != null && obj === obj.window

  • jQuery.fx.interval:默认值为 13(毫秒),但由于其与 requestAnimationFrame 配合不佳已被移除。它现在应该不再必要了。

  • jQuery.nodeName:请使用 element.nodeName.toLowerCase()

  • jQuery.now:请使用 Date.now()

  • jQuery.parseJSON:请使用 JSON.parse。

  • jQuery.trim:请使用 String.prototype.trim。

  • jQuery.type:原始类型请使用 typeof,数组使用 Array.isArray,对象使用 instanceof。或者使用 Object.prototype.toString.call(value)

  • jQuery.unique:请使用 jQuery.uniqueSort

链接 重大变更:移除未公开的 Array 方法

jQuery 4.0 从 jQuery 原型中移除了 pushsortsplice。这些方法是原生 Array 原型同名方法的副本,但从未公开记录且不打算供公共使用。由于某些插件可能使用了它们,我们仍将其标记为重大变更。

链接 精简版重大变更:移除 callbacksdeferredqueue 模块

jQuery 4.0 的精简版 (slim build) 不再包含 callbacksdeferredqueue 模块。如果您需要这些模块,请使用完整版,或使用原生 Promise 对象。

链接 重大变更:移除 jQuery.fn.init() 中未公开的 root 参数

rootjQuery.fn.init() 的第三个参数,但从未公开记录且仅供内部使用。此外,自 jQuery 1.9 移除 jQuery.sub() 以来,它已不再必要。

链接 重要修复:在 package.json 中添加 exports

jQuery 导出多种构建版本以供不同环境使用。这包括作为通用模块 (UMD) 和 ESM 模块的默认构建、UMD 和 ESM 的精简构建,以及用于在 JSDOM 等 DOM 模拟器中运行 jQuery 的 factory 构建。package.json 中的 exports 字段用于指定不同环境使用的构建。此变更在大多数情况下不会影响现有代码,但它是确保 jQuery 能在更广泛的环境中使用的重要修复。

链接 潜在重大变更:jQuery 源码不再使用 AMD 模块编写

jQuery 的源代码已转换为使用 ES 模块而非 AMD 模块。虽然这具有多种优势,但一些用户可能此前一直在使用 RequireJS 等 AMD 加载器直接导入 jQuery 源码。此变更可能会影响这些用户,但预计大多数用户仍能无缝继续使用 jQuery。主 jQuery 文件仍构建为 UMD 模块,因此可在 AMD 和非 AMD 环境中使用。

链接 CSS

链接 重大变更:大多数无单位数值不再自动添加 px

在设置需要单位的 CSS 属性时,jQuery 4.0 切换了策略。此前,jQuery 会自动为无单位数值添加 px(除少数例外)。此行为已在 jQuery 4.0 中移除。

相反,jQuery 现在仅为已知必须使用 px 的有限属性组添加单位。此变更可能会影响依赖于旧行为的现有代码。

链接 重大变更:移除 opacity CSS 钩子

对于脱离文档流的元素,.css( "opacity" ) 在符合标准的浏览器中将返回空字符串,在 IE 中返回 "1"。该行为与大多数其他 CSS 属性一致,但可能会影响依赖返回值 "1" 的现有代码。

链接 数据 (Data)

链接 重要修复:Object.prototype 原型污染

jQuery 4.0 包含一项修复,确保支持与 Object.prototype 属性同名的事件和数据键,而不会覆盖原生属性。这可能会影响在数据对象上调用 hasOwnProperty 的代码(这种情况应该很少见)。

1
if ( elem.data().hasOwnProperty( "key" ) ) { /* ... */ }

切换到

1
2
if ( "key" in elem.data() ) { /* ... */ }
if ( Object.hasOwn( elem.data(), "key" ) ) { /* ... */ }

链接 延迟对象 (Deferred)

链接 重大变更:移除 jQuery.Deferred.getStackHook

jQuery.Deferred.getStackHook 在 3.7.0 中重命名为 jQuery.Deferred.getErrorHook。它用于将原始错误传递给 jQuery.Deferred.exceptionHook。此前我们建议传递堆栈 (stack),但这与 source map 配合不佳。jQuery.Deferred.exceptionHook 可用于调试异步错误。

链接 事件 (Event)

链接 重大变更:停止对 focusin 和 focusout 事件的补丁

jQuery 4.0 不再对 focusinfocusout 事件进行补丁修复。这仅影响依赖这些事件与 focusblur 之间触发顺序的代码。预计受影响的用户极少。主要是在 IE 中顺序可能不同:blur 可能在 focusout 之前触发,focusfocusin 之前触发。详情请参阅 #4362

链接 重大变更:jQuery.event.special 不再继承自 Object.prototype

这可能会影响在 jQuery.event.special 上调用 hasOwnProperty 的代码(这种情况应该很少见)。

链接 DOM 操作 (Manipulation)

链接 重要功能:添加对可信类型 (Trusted Types) 的支持

jQuery 4.0 为所有 DOM 操作方法添加了对 可信类型 (Trusted Types) 的支持。预计此变更不会影响现有代码,但它是提升安全性的重要功能。

链接 潜在重大变更:避免在 buildFragment 中拼接字符串

此变更是为了支持 可信类型。目前尚不完全清楚有哪些实际用例会受影响,但我们将其列出以防万一。

链接 重要修复:不再从脚本中移除 HTML 注释和 CDATA 部分

浏览器现在无需 jQuery 协助即可处理这些内容。预计此变更不会影响现有代码,但这是一个重要修复,因为 jQuery 之前的移除逻辑并非 100% 准确。

链接 选择器 (Selector)

链接 重要修复:将 jQuery 选择上下文逻辑移植到原生选择器

长期以来,jQuery 拥有一个可替代 Sizzle 的极简选择器引擎。该引擎缺少 Sizzle 处理选择上下文的一些逻辑。此变更将这些逻辑移植到了原生选择器引擎,可能会影响依赖旧行为的代码。例如,在使用原生引擎时,$div.find( "> *" ) 不再报错。此外,给定以下 HTML:

1
2
3
<div id="parent">
<span></span>
</div>

以下代码在 jQuery 4.0 中返回 0 个结果:

1
2
const $div = $( "#parent" );
$div.find( "div span" );

这通常是符合预期的行为。

链接 重大变更:停止支持旧版的自定义伪类

Sizzle wiki 中的参考:https://github.com/jquery/sizzle/wiki#-backwards-compatible-plugins-for-pseudos-with-arguments