jQuery 1.8 Beta 1:了解新特性(和即将移除的特性)
各位 jQuery 用户大家好!我们已经有一段时间没有更新了,但我们并没有闲着。jQuery 核心团队一直在努力开发 jQuery 1.8,现在我们的第一个 beta 版本已经发布了!您可以在 jQuery CDN 上获取代码
请在您的当前 jQuery 代码上尝试一下,并告诉我们您的使用体验。如果您遇到任何问题,请提交错误报告,附上测试用例,并确保您提到正在测试 jQuery 1.8 Beta 1 版本。
本月晚些时候,在jQuery 大会上,我们将发布更多激动人心的 jQuery 新闻,之后还会在博客上进行发布。
jQuery 现在为互联网上大约一半的主要网站提供支持;这是一个巨大的成功,但我们不会止步不前。在过去六年中,网络浏览器及其运行的设备发生了翻天覆地的变化。Web 开发流程正在不断发展,以适应正在发生的变化。作为回应,jQuery 也在不断发展。
这种发展的一部分不仅在于了解要添加什么,还在于了解要删除什么。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 自定义构建版本在压缩和 gzip 之后将大约为 21KB。
但是,不用担心,构建您自己的 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>
标签,它将运行脚本。开发者有时会忘记这一点,向 jQuery 传递来自不受信任的来源(如 URL 或用户输入)的字符串。在这些情况下,有人可能会向页面注入脚本,从而窃取 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() 中的脚本标签 AJAX 请求期间静默忽略错误
- #11778: 缓存的 XHR 请求仍应异步解析
属性
构建
- #11767: 支持无效果的自定义构建
- #11789: 更新 README 以描述 grunt 构建系统
- #11856: 将尺寸模块化
- #11857: 将 css 模块化
- #11865: 将偏移量模块化
核心
CSS
- #10373: `document.defaultView` => `window`
- #10413: 隐藏父级元素的 "box-sizing: border-box" 子级元素的 width、innerWidth、innerHeight、outerWidth、outerHeight 不准确
- #10679: CSS3 供应商前缀支持
- #11004: 当 box-sizing 为 border-box 时,getWH 错误地删除了填充和边框宽度
- #11787: 删除 jQuery.curCSS
数据
- #10589: 删除 $.fn.data("events")
延迟
- #11010: 使 Deferred.then == Deferred.pipe 像 Promise/A 一样
- #11011: 允许使用传统的选项对象作为 $.Callbacks 标志
- #11736: 删除 Deferred .isResolved() 和 .isRejected()
- #11749: 当将多个 Deferred 对象传递给 $.when() 时,保留上下文对象
尺寸
- #6724: 移动版 Safari(iPhone)中的 $(window).height() 错误
- #10877: 将 outerWidth/Height 设为 setter
- #11293: 读取空 TD 的宽度或 outerWidth 会更改列宽度值
- #11604: 将 $(elem).width(-val) 从无操作改为 $(elem).width(0)
- #11724: Firefox 12 中 $(document).height() 已更改
效果
- #7109: 在 WebKit 上,动画宽度从无效宽度开始
- #7157: 动画回调显示元素仍为 ":animated"
- #8387: jQuery 1.5 的隐藏/显示问题在 WebKit 浏览器上的内联和内联块元素上存在闪烁问题
- #8627: .animate() 在 IE 上的 letterSpacing 上失败(1.5.1 中的回归)
- #8892: 在对象显示时,使用 fadeIn() 和 jQuery.fx.off = true 时,回调被提前触发
- #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: 错误:"change" 事件处理程序在 IE7 和 IE8 上手动触发时未执行
- #11621: 在 document 上触发事件不会冒泡到窗口
- #11718: 弃用 .data() 事件
- #11719: 弃用 .bind("ready") 事件
- #11731: 弃用 "hover" 伪事件
- #11733: 弃用 .load()、.unload() 和 .error() 方法
- #11786: 弃用 .toggle( handler, handler, … ) 签名
操作
- #8894: 在 clone() 之后调用的 appendTo() 及类似方法在 IE 中返回不正确的 jQuery 集合
- #10324: 克隆在 IE9 中不复制 object 元素的 innerHTML
- #11231: Append、Prepend、After、Before 应接受数组作为第一个参数
- #11338: .replaceWith() 和断开连接的节点的行为不一致。
- #11566: 当节点为 DocumentFragment 时,node.append 等不起作用
- #11617: 定义一个 $.parseHTML 方法来创建 HTML 片段
偏移量
选择器
- #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 迁移到 "unstable" 状态
遍历
- #9800: 新方法:.addBack(取代 .andSelf)
- #11543: .has 在分离的元素上不起作用
- #11706: `.has()` 在文档片段上失败
- #11738: 删除 .closest(Array) 返回 Array
未分类
- #11325: 改善 domManip/buildFragment/clean
- #11435: 删除过时的测试代码以从 .data 的返回值中删除 toJSON
- #11777: 为 jQuery 核心添加 EditorConfig 文件支持
jQuery 会创建一个在线工具供用户构建自己的自定义版本吗?
我注意到文件大小又变大了。这意味着瘦身过程是从 1.9 开始,还没有开始吗?
此外:感谢你们的辛勤工作!我真的很喜欢所做出的决定以及 jQuery 的发展方向。
@Blaise:jQuery 的模块化可能不会成为在线工具。虽然创建自定义构建相当容易,但自定义构建旨在满足对大小非常敏感的应用程序用户的要求。大多数用户可能应该继续从 CDN 加载 jQuery 以获得最佳性能。
另外,文件大小比 1.7.2 小,虽然没有小很多。是的,随着 1.9 中 $.browser 和 $.sub 以及其他一些小部分的删除,大小应该会大幅减少。
太好了,听起来很不错!感谢你们的辛勤工作!
干得好!出于兴趣,如果 $.browser 和 $.sub 要在 1.9 中移除,为什么我们不能在 1.8 的自定义构建中也排除它们?
@Mr. C:我今天实际上向团队建议了一个可以排除的“deprecated.js”,其中包含一些这些内容。我会把一个 pull 请求整理出来,除非有人抢先一步。
哇……修复了这么多问题……给你们团队点赞!:)
非常好,非常棒。我喜欢 jQuery 的发展方向!
感谢你们的辛勤工作。有一点 - “春季大扫除”中的插件仓库链接已失效。
jQuery 真是太棒了!感谢你们所做的一切!
我理解浏览器检测不是构建网页的最佳方式。然而,现实情况是,每个浏览器似乎总是有细微问题。有时,我们需要知道正在运行哪个浏览器。
例如,如果错误#11500(“change”事件处理程序在 IE7 和 IE8 中手动触发时未执行)影响我的页面,我需要添加代码来处理它,并且只希望该代码在这些特定的浏览器上运行。
如果没有浏览器检测,我需要编写笨拙的代码,通过 Modernizr 测试各种功能来猜测代码是否在 IE7 或 IE8 中运行,或者自己解析用户代理字符串并尝试猜测我的代码所在的浏览器(和模拟模式)。
是的,劝阻人们将浏览器检测用于显示/HTML/CSS 工作,但我们始终需要了解我们正在运行的浏览器的确切版本!
jquery.com 仍在使用 1.4.2 :/
@Glen,这就是为什么你可以通过自己解析 UA 或使用兼容性插件(自担风险)来进行自己的猜测。
@Bachinchi: /*! jQuery v1.6.4 https://jqueryjs.cn/ | http://jquery.org/license */ 似乎它使用的是 1.6.4,而不是 1.4.2
@gnarf 谢谢!
我认为你对弃用太宽容了。如果某些功能有害,请立即在 1.7 版本中弃用它们。为什么还要等?
或者,既然你现在已经非常模块化了,也许你可以将旧版功能分离到一个“legacy”模块中?
在 2.0 中将 IE < 9 代码移动到插件会很不错,可惜我们还得等 4 年才会实现。希望自定义构建能够在更多人转向像 zepto 那样写得不好的东西之前弥合这个差距。
关于模块化,作为 AMD 支持的一部分,jQuery 的不同模块会调用 define() 吗,例如 define( “jquery/ajax”, … ),以便它们可以被符合 AMD 的加载器包含?
@Jeff: 同意。