我遇到过一种情况,我想要关注一个输入标签,如果它存在,或者它是容器,如果它没有。所以我想到了一种明智的做法:
document.querySelector('.container input, .container').focus();
有趣的是,querySelector
始终返回.container
元素。
我开始调查并发现,无论放置不同选择器的顺序如何,querySelector
总是返回相同的元素。
例如:
var elem1 = document.querySelector('p, div, pre');
var elem2 = document.querySelector('pre, div, p');
elem1 === elem2; // true
elem1.tagName; // "P".
我的问题是:此行为的“原因”是什么以及“规则”(如果有的话)使P元素优先于DIV和PRE元素。
注意:在上述情况下,我提出了一个不太优雅但功能性的解决方案:
(document.querySelector('.container input') || document.querySelector('.container') ).focus();
答案 0 :(得分:6)
document.querySelector
仅返回匹配的第一个元素,从标记中的第一个元素开始。正如MDN所述:
返回文档中的第一个元素(使用depth-first 通过第一个元素预先遍历文档的节点 文档标记并按顺序迭代顺序节点 与指定的选择器组匹配的子节点数量。
如果您希望所有元素与查询匹配,请使用document.querySelectorAll
(docs),即document.querySelectorAll('pre, div, p')
。这将返回匹配元素的数组。
答案 1 :(得分:4)
官方document说,
返回文档中的第一个元素(使用文档节点的深度优先预先遍历遍历|文档标记中的第一个元素,并按子节点数量的顺序迭代顺序节点)与指定的选择器组匹配
这意味着,在您的第一种情况下.container
是父元素,因此它将首先匹配并返回。在第二种情况下,该段落应该是文档中的第一个元素,同时与其他pre
和div
进行比较。所以它被退回了。
答案 2 :(得分:1)
这正是.querySelector()
的预期行为 - 它找到 所有 文档中与您的查询匹配的元素,然后返回第一。
那不是"你列出的第一个",它是"文件中的第一个"。
这实际上就像CSS选择器一样。选择器p, div, pre
和pre, div, p
是相同的;它们都匹配三种不同类型的元素。因此,elem1.tagName == 'P'
的原因只是您在任何<p>
或<pre>
代码之前的页面上有<div>
。