2014-09-26 254 views
0

所以我最近玩弄了querySelector,并且在尝试选择后代元素时注意到了一些非常奇怪的行为。使用querySelector查找后代元素返回意外的结果

以下面的标记为例:

<div id="parent"> 
    <div id="foo"> 
    <div id="bar"></div> 
    </div> 
</div> 

如果我想查询从#parent元素的背景下,这个DOM树,我可以做到以下几点:

var parent = document.getElementById('parent'); 
parent.querySelector('div') 

这按预期返回#foo元素。现在,如果我想通过仅参考标签名称来获得#bar元素,我可以做以下任一:

var parent = document.getElementById('parent'); 
parent.querySelector('div div') 
parent.querySelector('div > div') 

相反,无论是选择字符串返回#foo元素,而不是#bar元素?但是,将上下文元素(#parent)更改为跨度可以解决问题?好像上下文元素影响它如何解释选择器字符串。或者,jQuery的选择器引擎按预期执行。

我创建了一个说明问题的CodePen

我不认为这是一个错误,因为结果在多个浏览器(我使用的是Chrome 37)是一致的。我想我的问题是,我错过了什么吗?这是规范的一部分吗?有没有人有这种行为的解释?

任何了解,将不胜感激,谢谢, 瑞恩

回答

1

the docs,“选择器是针对在整个DOM树,其中所述元件位于的上下文中,给定的元素进行评价。”

也就是说,它不是一个jQuery风格的“找到一个匹配从这里开始的选择器路径的元素”。

#parent #foo绝对匹配div divdiv > div,当从DOM树级别查看时,根据规范。

它“作品”当你改变#parentspan因为#parent #foo不再匹配div div,并#foo #bar是新的第一场比赛。

+0

感谢您的回复,但我仍然有点困惑。如果选择器字符串的第一个片段实际上是针对上下文元素进行评估的,而不是'parent.querySelector('div')'选择自己?这种不一致是我发现特别令人不安的。 – user141350 2014-09-26 21:36:11

+0

不是。任何选择器字符串的* *片段都不会被评估。父对象的子元素将根据* complete *选择器字符串进行评估。 '#foo'与'div div'相匹配,当它的父母是'div'时,而不是当父母是'span'时。 – 2014-09-26 21:50:41

+0

也许这只是我,但同时具有'parent.querySelector('div')'和'parent.querySelector('div div')'返回相同的元素似乎是一个坏主意。 – user141350 2014-09-26 21:57:18