12

根据http://api.jquery.com/category/selectors/我们可以在 jQuery 中使用大量的 CSS 选择器,但是:nth-last-child()这里没有提到 eg。但是,当我测试以下内容时(使用来自 Google 的 jQuery 1.7.1),它实际上适用于 Firefox、Chrome 和 IE 9,但不适用于 IE 8 仿真模式下的 IE 9:

$('li:nth-last-child(2)').css('color', 'red');

那么发生了什么?看起来好像 jQuery 生成了 CSS 代码,li:nth-last-child(2) { color: red }并且以某种方式注入了它,然后在支持使用的选择器的浏览器上运行良好。但这很奇怪。

最重要的是,是否有一些技巧可以让 jQuery 在所有浏览器上都支持此类选择器?

4

1 回答 1

37

虽然 jQuery 在其主页上宣传符合Selectors level 3标准,但它并没有完全实现该规范。在其自己的选择器文档中,它阐明了它“[借用] CSS 1-3,然后[添加]它自己的”选择器。1

从 jQuery 1.9 开始,Sizzle(其底层选择器库)几乎支持 3 级标准中的所有选择器,但以下情况除外:

以下 3 级选择器在 jQuery 1.9 和更新版本中实现,但不是在jQuery 1.8 或更早版本2中实现:

此外:

  • :lang(),在 CSS2 中引入,也不见了。

您的选择器似乎在 Firefox、Chrome 和 IE9 中工作的原因是 jQuerydocument.querySelectorAll()在回退到 Sizzle 之前首先将选择器字符串传递给本机实现。由于它是一个有效的 CSS 选择器,document.querySelectorAll()将成功返回一个节点列表供 jQuery 使用,从而避免使用 Sizzle。

如果document.querySelectorAll()失败,jQuery 会自动回退到 Sizzle。有许多情况可能导致它失败:

  • 选择器无效、不受支持或无法使用(有关详细信息,请参阅选择器 API 规范)。

  • document.querySelectorAll()方法本身不受支持(jQuery 实际上用一个简单的 if 语句对此进行了测试,因此它不会在这个词的意义上失败,但你明白了)。

在您的情况下,虽然 IE9 和 IE8 实现了document.querySelectorAll(),但 IE8 不支持:nth-last-child(). 由于 jQuery/Sizzle 也没有实现:nth-last-child(),因此没有可使用的回退行为,导致 IE8 完全失败。

如果您至少无法将 jQuery 更新到 1.9(向后兼容的发布分支),您始终可以使用自定义选择器扩展来自己实现缺少的伪类。但是,由于 jQuery 1.9 在保持与旧 IE 版本的兼容性的同时增加了对上述选择器的支持,因此如果您需要兼容性,最好至少更新到该版本。


1 它确实支持:contains(), 最后在该规范的旧 CR 修订版中定义,后来被删除,以及:not()从标准扩展。这个问题涵盖了 jQuery 的实现和当前标准之间的差异。

2 A few other selectors (like the + and ~ sibling combinators, :empty, :lang() and some CSS2 attribute selectors) were going to be dropped as well during jQuery's early development, just because John Resig didn't think anybody would use them. Almost all of them made it into the final release after some more tests were made available. :lang() was the only one that never made it into any release before 1.9, as stated above.

于 2012-07-31T17:05:45.490 回答