jQuery Core 1.9 升级指南
- 概述
- jQuery Migrate 插件
- jQuery 1.9 中值得注意的更改
- .toggle(function, function, ... ) 已移除
- jQuery.browser() 已移除
- .live() 已移除
- .die() 已移除
- jQuery.sub() 已移除
- .add()
- .addBack( selector ) 替换了 .andSelf()
- .after(), .before() 和 .replaceWith() 与未连接的节点
- .appendTo, .insertBefore, .insertAfter 和 .replaceAll
- Ajax 事件应附加到文档
- .trigger()ed "click" 事件中的复选框/单选按钮状态
- 触发的 "focus" 事件的顺序
- jQuery(htmlString) 与 jQuery(selectorString)
- .data() 方法不触发事件;带有句点的名称
- jQuery 集合中未连接节点的排序
- 在 HTML 内容中加载和运行脚本
- .attr() 与 .prop()
- $("input").attr("type", newValue) 在 oldIE 中
- "hover" 伪事件
- .selector 属性在 jQuery 对象中
- jQuery.attr()
- jQuery.ajax 返回空字符串的 JSON 结果
- jQuery.proxy() 上下文
- .data("events")
- Event 对象的已移除属性
- API 方法的未记录参数
- 其他未记录的属性和方法
link 概述
jQuery 1.9 删除或修改了几个过去行为不一致或效率低下的 API。这些更改大部分在以前版本的 jQuery(尤其是 1.7 和 1.8)中已通过其 弃用 预示。
在进行这些更改时,该团队的目标是修复使 jQuery 不一致或难以使用的问题,并在此过程中提高文件大小和整体性能。
这个列表具有欺骗性。这些更改中的大多数都针对特殊情况和边缘情况,还有一些更改是针对 jQuery 的历史行为存在问题而广泛要求的更改。作为第一步,查看你的代码是否有效的方法是按照以下说明同时使用 jQuery 1.9 和 Migrate 插件。
目前,本指南作为标准 jQuery API 文档的附录,这些页面可能不会描述 1.9 版本的行为。请耐心等待,我们更新 api.jquery.com 上各个页面的文档以反映 1.9 中的更改。
link jQuery Migrate 插件
我们意识到现有站点和插件可能会受到这些更改的影响,并提供 jQuery Migrate 插件作为过渡升级路径。以下各个描述表明 1.9 中更改的行为是否可以通过使用 jQuery Migrate 插件来恢复。请注意,jQuery 1.9 中的所有更改也适用于 jQuery 2.0,并且 jQuery Migrate 插件也可用。
jQuery Migrate 插件的未压缩开发版本包括控制台日志输出,以在使用特定已弃用和/或已删除的功能时发出警告。这使其成为查找和修复现有 jQuery 代码和插件中问题的宝贵迁移调试工具。它可以与 1.6.4 之前的 jQuery 内核版本一起用于诊断。
插件的压缩版本不会生成任何日志输出,并且可以在需要 jQuery 1.9 或更高版本但必须同时使用较旧的不兼容 jQuery 代码或插件时在生产站点上使用。理想情况下,这只能作为短期解决方案使用,但这是您需要做出的决定。
有关更多信息,请参阅 jQuery Migrate 插件。
link jQuery 1.9 中的注意事项更改
以下列表并不代表为 jQuery 1.9 所做的所有更改,只是我们预期的可能以破坏现有代码的方式影响行为的更改。有关更改的完整详细列表,请参阅 jQuery 博客 上的发布公告中的变更日志或访问 bugs.jquery.com。
link 删除了 .toggle(function, function, ... )
这是 .toggle()
的“单击元素以运行指定函数”签名。它不应与未弃用的 .toggle()
的“更改元素的可见性”混淆。前者被删除是为了减少混淆并提高库中模块化的可能性。jQuery Migrate 插件可用于恢复该功能。
link 删除了 jQuery.browser()
自 jQuery 1.3 起,jQuery.browser()
方法已被弃用,并在 1.9 中移除。如有需要,可作为 jQuery Migrate 插件的一部分使用。我们建议使用诸如 Modernizr 之类的库进行特性检测。
链接 .live() 已移除
自 jQuery 1.7 起,.live()
方法已被弃用,并在 1.9 中移除。我们建议升级代码以改用 .on()
方法。例如,为了完全匹配 $("a.foo").live("click", fn)
,可以编写 $(document).on("click", "a.foo", fn)
。有关更多信息,请参阅 .on() 文档。在此期间,可以使用 jQuery Migrate 插件来恢复 .live()
功能。
链接 .die() 已移除
自 jQuery 1.7 起,.die()
方法已被弃用,并在 1.9 中移除。我们建议升级代码以改用 .off()
方法。例如,为了完全匹配 $("a.foo").die("click")
,可以编写 $(document).off("click", "a.foo")
。有关更多信息,请参阅 .off() 文档。在此期间,可以使用 jQuery Migrate 插件来恢复 .die()
功能。
链接 jQuery.sub() 已移除
jQuery.sub()
方法已移至 jQuery Migrate 插件。证明其有价值的用例数量不足以证明将其保留在核心部分中。jQuery Migrate 插件添加了此功能。
链接 .add()
.add()
方法始终应按文档顺序返回其结果。在 1.9 之前,如果上下文或输入集以断开连接的节点(不在文档中)开头,.add()
不会按文档顺序对节点进行排序。现在,节点始终按文档顺序返回,断开连接的节点放置在集合的末尾。
链接 .addBack( selector ) 替换 .andSelf()
从 jQuery 1.8 开始,.andSelf()
方法已被弃用,转而使用 .addBack()
方法,我们认为该方法更适合描述此方法的作用——“将前一组结果‘添加回来’”。新方法接受一个可选选择器,可在将前一组添加到当前组之前使用该选择器对前一组进行筛选。因此,$("section, aside").children("ul").addBack("aside")
会生成一个集合,其中包括所有 aside
节点以及 section
和 aside
节点的 ul
子项,按文档顺序排列。虽然 .andSelf()
方法在 1.9 中仍然有效,但我们建议尽快切换名称。jQuery Migrate 插件将对使用 .andSelf()
发出警告。
链接 .after()、.before() 和 .replaceWith() 与未连接的节点
在 1.9 之前,如果集合中的第一个节点未连接到文档,.after()
、.before()
和 .replaceWith()
会尝试在当前 jQuery 集合中添加或更改节点,并且在这些情况下返回一个新的 jQuery 集合,而不是原始集合。这造成了几个不一致和明显的错误——该方法可能会或可能不会根据其参数返回一个新结果!从 1.9 开始,这些方法始终返回原始未修改的集合,并且尝试对没有父级的节点使用 .after()
、.before()
或 .replaceWith()
没有效果——也就是说,集合或它包含的节点都不会更改。
链接 .appendTo、.insertBefore、.insertAfter 和 .replaceAll
从 1.9 开始,这些方法始终返回一个新的集合,使其可以与链接和 .end()
方法一致地使用。在 1.9 之前,它们仅在存在单个目标元素时才返回旧集合。请注意,这些方法始终返回附加到目标元素的所有元素的聚合集合。如果目标选择器未选择任何元素(例如,$(elements).appendTo("#not_found")
),则结果集合将为空。
链接 Ajax 事件应附加到文档
从 jQuery 1.9 开始,全局 Ajax 事件(ajaxStart、ajaxStop、ajaxSend、ajaxComplete、ajaxError 和 ajaxSuccess)仅在 document
元素上触发。更改程序以在文档上侦听 Ajax 事件。例如,如果代码当前如下所示
1
|
|
将其更改为
1
|
|
链接 .trigger()ed “click” 事件中的复选框/单选按钮状态
当用户单击复选框或单选按钮时,事件处理程序会看到节点处于如果未在节点上调用 event.preventDefault()
则会处于的状态——本质上是它的新状态。因此,例如,如果用户单击未选中的复选框,则事件处理程序将看到一个选中的框。在 1.9 之前,由 .trigger("click")
或 .click()
触发的合成事件会看到复选框处于与用户操作相反的状态。这已在 1.9 中得到修复,以反映与用户发起的操作相同的选中状态。
链接 触发的“focus”事件的顺序
当用户单击或制表进入表单元素以使其获得焦点时,浏览器首先为先前获得焦点的元素触发一个 blur 事件,然后为新元素触发一个 focus 事件。在 1.9 之前,使用 .trigger("focus")
或 .focus()
触发的 focus 事件会为新元素触发一个 focus 事件,然后为上一个元素触发一个 blur 事件,最后才真正使元素获得焦点。在 1.9 中,此行为已更改为反映与用户导致焦点更改相同的顺序。
对于原生 DOM 焦点事件,只有当目标元素尚未获得焦点并且能够成功获得焦点时,浏览器才会调用焦点事件处理程序。jQuery 一直确保对 .trigger("focus")
或 .focus()
的调用始终运行任何附加的事件处理程序,即使该元素无法获得焦点,jQuery 1.9 也将继续这样做。这与 DOM .focus()
方法的行为不同,在许多情况下,该方法不会调用事件处理程序,包括元素已经获得焦点或元素被禁用。
不幸的是,所有版本的 Internet Explorer(6 到 10)都会异步触发焦点事件。当您在 IE 中使用 .trigger("focus")
时,jQuery 不会“看到”稍后发生的异步焦点事件,因此它会触发自己的事件以确保始终如上所述发生焦点事件。这会导致对事件处理程序进行两次调用。要避免这种双重调用(但有风险导致根本不调用事件处理程序),请直接使用 DOM 焦点方法,例如 $("selector").get(0).focus()
。
link jQuery(htmlString) 与 jQuery(selectorString)
在 1.9 之前,如果字符串中任何地方有 HTML 标记,则该字符串会被视为 HTML 字符串。这可能会导致意外执行代码并拒绝有效的选择器字符串。从 1.9 开始,只有当字符串以小于号 (“<
”) 字符开头时,才将其视为 HTML。可以使用 Migrate 插件来恢复 1.9 之前的行为。
如果已知一个字符串是 HTML,但可能以不是 HTML 标记的任意文本开头,请将其传递给 jQuery.parseHTML()
,该函数将返回表示标记的 DOM 节点数组。可以从中创建一个 jQuery 集合,例如:$($.parseHTML(htmlString))
。例如,在处理 HTML 模板时,这将被视为最佳实践。此更改不会影响对文字字符串的简单使用,例如 $("<p>Testing</p>").appendTo("body")
。
要点:传递给 jQuery()
的以小于号以外的字符开头的 HTML 字符串将被解释为选择器。由于该字符串通常不能解释为选择器,因此最可能的结果是 Sizzle 选择器引擎抛出的“无效选择器语法”错误。使用 jQuery.parseHTML()
来解析任意 HTML。
当使用 jQuery Migrate 插件时,它将使用旧规则来确定传递给 $()
的字符串是否“看起来像 HTML”。
link .data() 方法未触发的事件;带有句点的名称
.data()
方法有一个未记录且性能极差的方法来监视值の設定和获取,该方法已在 1.9 中删除。这以一种好的方式影响了包含句点的 data 名称的解释。从 1.9 开始,对 .data("abc.def")
的调用仅检索名称“abc.def”的数据,而不会只检索“abc”。请注意,较低级别的 jQuery.data()
方法从未支持事件,因此它没有发生更改。jQuery Migrate 插件不会恢复此案例的旧行为。
链接 jQuery 集合内断开节点的排序
在许多版本中,几乎所有返回新节点集合的 jQuery 方法都使用文档顺序对结果集合进行排序。(有一些方法如 .parents()
,它以反向文档顺序返回其结果,但这些例外情况已记录在案,并且在 1.9 中没有改变。)
在 1.9 之前,包含一些已连接和一些断开节点的集合将被不一致地排序,具体取决于断开节点是否领导原始未排序集合。从 1.9 开始,已连接节点始终按文档顺序放置在集合的开头,断开节点放置在它们后面。jQuery Migrate 插件不会恢复旧行为,旧行为有点随机且不可预测。
链接 在 HTML 内容中加载和运行脚本
在 1.9 之前,任何接受 HTML 的方法(例如 $()、.append() 或 .wrap())都会执行 HTML 中的任何脚本,并将其从文档中删除以防止再次执行它们。当脚本可能被删除并使用 .wrap()
等方法重新插入文档时,这仍然会中断。从 1.9 开始,插入文档的脚本将被执行,但保留在文档中并标记为已执行,因此即使它们被删除并重新插入,也不会再次执行它们。
尽管有此更改,但将可执行 JavaScript 混入 HTML 标记中是一种非常糟糕的做法;它具有设计、安全、可靠性和性能影响。例如,HTML 中包含的外部脚本标记以同步方式获取,然后进行评估,这可能需要大量时间。没有界面通知这些脚本何时或是否加载,或在出现错误时采取纠正措施。
尝试通过克隆现有脚本标记并将该克隆注入文档来加载脚本的代码将不再起作用,因为克隆的脚本标记已标记为已执行。要加载新脚本,请改用 jQuery.getScript()
。
链接 .attr() 与 .prop()
jQuery 1.6 引入了 .prop()
方法,用于设置或获取节点上的属性,并废弃了使用 .attr()
来设置属性。但是,1.9 之前的版本继续支持在特定情况下使用 .attr()
。这种行为以向后兼容性的名义导致在区分属性和属性的选择器中使用时造成混乱。
例如,复选框上的布尔属性(如 checked
和 disabled
)受此更改影响。"input[checked]"
的正确行为是选择具有 checked
属性的复选框,无论其字符串值如何,也无论其当前状态如何。相比之下,"input:checked"
选择当前已选中的复选框,这反映在其布尔 (true
或 false
) checked
属性中,例如,当用户单击该框时会受到影响。1.9 之前的版本有时无法使用这些选择器选择正确的节点。
以下是在复选框上设置 checked
时正确使用的示例;相同规则适用于 disabled
。请注意,只有属性才能始终如一地反映和更新所有浏览器中复选框的当前状态;您很少需要设置属性。
1
2
3
4
5
6
7
8
9
|
|
input
元素上的 value
属性与属性是这种歧义的另一个示例。该属性通常反映从 HTML 标记中读取的值;该属性反映当前值。由于 .val()
方法是获取或设置表单元素值的首选 jQuery 方式,因此这种混淆通常不会影响用户。
但是,当使用类似于 "input[value=abc]"
的选择器时,它应该始终按值属性进行选择,而不是用户对属性所做的任何更改,例如,他们从文本输入中键入。从 jQuery 1.9 开始,此行为正确且一致。早期版本的 jQuery 有时会在应该使用属性时使用属性。
jQuery Migrate 插件恢复了旧的属性与属性规则。
link $("input").attr("type", newValue) in oldIE
在 1.9 版本之前,jQuery 会在所有浏览器中抛出异常,以尝试在输入或按钮元素上设置 type
属性。这样做是为了适应最低公分母;如果您尝试更改输入元素的类型,IE 6/7/8 会抛出错误。从 jQuery 1.9 开始,如果浏览器允许,我们允许您设置元素的类型。但是,您自己的代码需要意识到,在 oldIE 上尝试这样做仍然会抛出错误。当您尝试设置 type
属性但不会抛出 JavaScript 错误时,jQuery Migrate 插件会发出警告。
link “hover” 伪事件
从 1.9 开始,事件名称字符串 “hover”
不再作为 “mouseenter mouseleave”
的同义词支持。这允许应用程序附加和触发自定义 “hover” 事件。更改现有代码是一个简单的查找/替换,并且 jQuery Migrate 插件中也支持 “hover” 伪事件,以简化迁移。
link jQuery 对象上的 .selector 属性
jQuery 对象上已弃用的 .selector
属性的剩余目的是支持已弃用的 .live()
事件。在 1.9 中,jQuery 不再尝试在链式方法中维护此属性,因为 .live()
从不支持使用链式方法。请勿在 jQuery 对象上使用 .selector
属性。jQuery Migrate 插件不会尝试维护此属性。
link jQuery.attr()
在 1.9 中,我们使用 pass 参数删除了未记录的签名 jQuery.attr(elem, name, value, pass)。任何依赖此项的代码都应重写,但 jQuery Migrate 插件可以提供向后兼容的行为,并且如果使用此签名,它会发出警告。
link jQuery.ajax 返回空字符串的 JSON 结果
在 1.9 之前,期望返回数据类型为 JSON 或 JSONP 的 ajax 调用会将空字符串的返回值视为成功案例,但会向 success 处理程序或 promise 返回 null。从 1.9 开始,为 JSON 数据返回的空字符串被认为是格式错误的 JSON(因为它就是);这现在会抛出错误。使用错误处理程序来捕获此类情况。
link jQuery.proxy() 上下文
1.9 中的新增功能,使用 jQuery.proxy 调用返回的函数,如果上下文为假值,将保留其 this
对象以供提供的函数使用。以前,如果上下文为假值,则会转换为全局对象 (window),如果为 null/undefined,或者封装在一个对象中(例如,new Boolean(false))。
链接 .data("events")
在 1.9 之前,如果没有任何其他代码使用名称为“events”的数据元素定义数据元素,则可以使用 .data("events")
检索元素的 jQuery 未记录的内部事件数据结构。此特殊情况已在 1.9 中删除。没有公开的接口来检索此内部数据结构,并且它仍然未记录。但是,jQuery Migrate 插件会为依赖它的代码恢复此行为。
链接 已删除的事件对象属性
Event
对象的 attrChange
、attrName
、relatedNode
和 srcElement
属性在 jQuery 1.7 中已弃用,因为它们是非标准的,并且不是跨浏览器的;从 jQuery 1.9 开始,它们不再被复制到传递给事件处理程序的 Event
对象中。在任何版本的 jQuery 中,仍然可以通过使用 event.originalEvent
而不是 event
在支持它们的浏览器中访问这些属性。jQuery Migrate 插件也会将这些属性添加回 Event
对象。
链接 API 方法的未记录参数
在 1.9 之前,几个 API 方法都有未记录的参数,这些参数会改变其行为,并可能导致意外错误使用或不正确的鸭子打补丁。这些参数现已删除。受影响的方法包括 jQuery.data()
、jQuery.removeData()
和 jQuery.attr()
。jQuery Migrate 插件不支持这些未记录的参数,因为经过重构的代码不再需要它们。
链接 其他未记录的属性和方法
以下内部属性和方法从未记录,并且已在 1.9 中删除。任何依赖它们的代码都应重写。
jQuery.deletedIds
jQuery.uuid
jQuery.attrFn
jQuery.clean()
jQuery.event.handle()
jQuery.offset.bodyOffset()