Javascript 多后代选择器、错误或误解?

Javascript 多后代选择器、错误或误解?,javascript,css,queryselector,Javascript,Css,Queryselector,以下两种选择节点的方法不应该产生相同的结果吗 let tmp = fruits.querySelector("ul:first-of-type li:first-of-type"); tmp = tmp.querySelector("span") vs (见实际行动) 我已经在firefox和chrome上测试过了。两种情况下的结果不同。谁能解释一下原因吗 堆栈代码段中的示例: let fruits=document.querySelector

以下两种选择节点的方法不应该产生相同的结果吗

let tmp = fruits.querySelector("ul:first-of-type li:first-of-type");
tmp = tmp.querySelector("span")    
vs

(见实际行动)

我已经在firefox和chrome上测试过了。两种情况下的结果不同。谁能解释一下原因吗

堆栈代码段中的示例:

let fruits=document.querySelector(“[data segment='fruits']”);
原木(水果);
设tmp=fruits.querySelector(“ul:类型的第一个li:类型的第一个”)
tmp=tmp.querySelector(“span”)
log(“工作:”)
console.log(tmp)
日志(“不工作:”)
console.log(fruits.querySelector(“ul:第一个类型li:第一个类型span”))
  • fruits
    • 橙子
    • 菠萝
    • apples
      • macintosh
      • granny smith
      • 富士
    • 香蕉
    • pears
  • 蔬菜
  • 颗粒
说明如下:

element=baseElement.querySelector(选择器);
返回值
baseElement
的第一个子元素,它与指定的
选择器组相匹配匹配时考虑整个元素层次结构,包括
baseElement
及其子元素集之外的元素;换句话说,
选择器
首先应用于整个文档,而不是
基本元素
,以生成潜在元素的初始列表。然后检查结果元素以查看它们是否是
baseElement
的后代。其余元素的第一个匹配项由
querySelector
方法返回

(我的重点。)

让我们考虑一个简化的例子:

console.log(document.getElementById(“a”).querySelector(“ulli span”)
  • a
    • B
el.querySelector(选择器)
如果您不知道它在后台是如何工作的,则会返回令人惊讶的结果

 el.querySelector(selector)
实际情况是这样的:

 (el, selector) => [...document.querySelectorAll(selector)].filter(node => el !== node && el.contains(node))[0]
请参见此示例:

const el=document.getElementById('outer');
常量选择器='span>span';
console.log(el.querySelector(selector.id);//日志“内部”,而不是“最内部”
//就像你做的一样
console.log([…document.queryselectoral(selector)].filter(node=>el!==node&&el.contains(node))[0].id)


我在3个不同的浏览器中运行了它,结果是一样的。最让我不安的是
水果。querySelector(“ul:first of type li:first of type”)
选择橙子
  • ,而
    水果。querySelector(“ul:first of type li:first of type span”)
    选择and的果实。我突然想到,你不能有一个以子代组合符开头的相对选择器——在作用域选择器中,:scope伪的唯一实例是强制性的。啊,@BoltClock,我记得你自己曾经为这个问题写过一个漂亮的标准答案。值得一提的是:我怀念那些日子(一旦你读过,请随意删除这段可怕的无关紧要的评论)@David:我不@BoltClock,我并不是太记得你写的一个具体的答案,只是我记得读过你的几个答案,在这些答案中,你按照一篇文章的思路写了一些东西——以一种引人入胜的方式——完整而详尽地回答了提出的问题。@David:哦,对了,“你已经写了”,而不是“你已经写了”。是的,我会的,虽然它可能与Sebastian在这里得到的大致相同,但我会引用DOM规范,而不是MDN(但MDN在这里很好)。
     (el, selector) => [...document.querySelectorAll(selector)].filter(node => el !== node && el.contains(node))[0]