根据http://api.jquery.com/category/selectors/,我们可以在jQuery中使用大量的CSS选择器,但是那里没有提到:nth-last-child()
。但是,当我测试以下内容时(使用jQuery 1.7.1来自Google),它实际上适用于Firefox,Chrome和IE 9,但不适用于IE 8中的IE 8仿真模式:
$('li:nth-last-child(2)').css('color', 'red');
那发生了什么事?看起来好像jQuery生成了CSS代码,比如li:nth-last-child(2) { color: red }
并以某种方式注入了它,然后在支持所用选择器的浏览器上正常工作。但这很奇怪。
最重要的是,是否有一些技巧可以让jQuery在所有浏览器上支持这样的选择器?
答案 0 :(得分:36)
虽然jQuery在Selectors level 3上宣传了home page标准的合规性,但它没有完全实现规范。在它自己的Selectors文档中,它澄清了它“[借用] CSS 1-3,然后[添加]自己的”选择器。 1
从jQuery 1.9开始,Sizzle(其基础选择器库)几乎支持3级标准中的所有选择器,但以下情况除外:
jQuery无法选择任何伪元素they are CSS-based abstractions of the document tree that can't be expressed through the DOM。
jQuery无法解析动态伪类,例如:link
/:visited
表示超链接,:hover
, :active
and :focus
表示用户交互。后一组伪类特别是基于状态而不是基于事件的,因此当元素输入并且离开时,您需要使用事件处理程序而不是伪类来运行代码/ em>这些状态。有关说明,请参阅this answer。
jQuery也无法解析namespace prefixes,因为它不支持namespacing in CSS。
以下3级选择器are implemented in jQuery 1.9 and newer,但不 jQuery 1.8或更早 2 :
:target
:root
:nth-last-child()
:nth-of-type()
:nth-last-of-type()
:first-of-type
:last-of-type
:only-of-type
此外:
:lang()
也缺失了。你的选择器似乎在Firefox,Chrome和IE9中工作的原因是因为jQuery首先将选择器字符串传递给本地document.querySelectorAll()
实现,然后再回到Sizzle。由于它是一个有效的CSS选择器,document.querySelectorAll()
将成功返回一个节点列表供jQuery使用,从而避免使用Sizzle。
如果document.querySelectorAll()
失败,jQuery会自动回退到Sizzle。有许多方案可能导致其失败:
选择器无效,不受支持,或者无法使用(有关详情,请参阅Selectors API spec)。
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()
,最后在this old CR revision of the spec中定义,然后再被删除,以及从标准中扩展:not()
。 jQuery的实现与当前标准之间的差异在this question。
2 一些其他选择器(如+
和~
兄弟组合器,:empty
,:lang()
和一些CSS2属性在jQuery的早期开发过程中,也会因为John Resig didn't think anybody would use them而被删除。经过一些更多测试后,几乎所有这些都进入了最终版本。 :lang()
是唯一一个在1.9之前没有进入任何版本的人,如上所述。