【问题标题】:Using querySelector to Find Descendant Elements Returns Unexpected Results使用 querySelector 查找后代元素返回意外结果
【发布时间】:2014-11-21 23:39:57
【问题描述】:

所以我最近一直在使用 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)。我想我的问题是;我错过了什么吗?这是规范的一部分吗?有人对此行为有解释吗?

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

【问题讨论】:

    标签: javascript selectors-api


    【解决方案1】:

    根据the docs,“选择器是在元素所在的整个 DOM 树的上下文中针对给定元素评估的。”

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

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

    当您将 #parent 更改为 span 时,它“有效”,因为 #parent #foo 不再匹配 div div,而 #foo #bar 是新的第一个匹配项。

    【讨论】:

    • 感谢您的回复,但我还是有点困惑。如果选择器字符串的第一个片段实际上是针对上下文元素进行评估的,那么parent.querySelector('div') 不应该选择自己吗?这种不一致是我觉得特别令人不安的。
    • 不。选择器字符串的 fragments 不会针对任何内容进行评估。父元素的子元素根据 complete 选择器字符串进行评估。 #foodiv div 匹配,当其父级为 div 时有效,而不是当其父级为 span 时。
    • 也许只有我一个人,但是让 parent.querySelector('div')parent.querySelector('div div') 返回相同的元素似乎是个坏主意。
    • @user141350 我完全同意。好像有点矛盾?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2017-11-14
    相关资源
    最近更新 更多