Element: querySelectorAll() 方法
Element 的 querySelectorAll() 方法返回一个静态(非实时)的 NodeList,代表一个与指定选择器组匹配的元素列表,这些元素是调用该方法的元素的后代。
语法
querySelectorAll(selectors)
参数
- 选择器 (selectors)
- 
一个包含一个或多个要匹配的选择器的字符串。该字符串必须是有效的 CSS 选择器字符串;如果不是,将抛出 SyntaxError异常。请注意,HTML 规范不要求属性值是有效的 CSS 标识符。如果 class或id属性值不是有效的 CSS 标识符,那么在使用它作为选择器之前,您必须对其进行转义,可以通过对该值调用CSS.escape(),或者使用 转义字符 中描述的一种技术。有关示例,请参见 转义属性值。选择器应用于整个文档,而不仅仅是调用 querySelectorAll()的特定元素。要将选择器限制在调用querySelectorAll()的元素上,请在选择器开头包含:scope伪类。请参见 选择器范围 示例。
返回值
一个非实时 NodeList,其中包含一个 Element 对象,对应于每个匹配至少一个指定选择器的后代节点。这些元素按文档顺序排列——即父节点在子节点之前,较早的兄弟节点在较晚的兄弟节点之前。
注意:如果指定的 selectors 包含 CSS 伪元素,则返回的列表始终为空。
异常
- SyntaxError- DOMException
- 
如果指定的 selectors字符串的语法无效,则抛出。
示例
获取所有具有自定义数据值的元素
此示例使用属性选择器来选择多个具有包含“funnel-chart-percent”的 data-name 数据属性的元素。
<section class="box" id="sect1">
  <div data-name="funnel-chart-percent1">10.900%</div>
  <div data-name="funnel-chart-percent2">3700.00%</div>
  <div data-name="funnel-chart-percent3">0.00%</div>
</section>
const refs = [
  ...document.querySelectorAll(`[data-name*="funnel-chart-percent"]`),
];
获取匹配列表
要获取元素 myBox 中包含的所有 <p> 元素的 NodeList
const matches = myBox.querySelectorAll("p");
此示例返回 myBox 中所有类为 note 或 alert 的 <div> 元素的列表
const matches = myBox.querySelectorAll("div.note, div.alert");
在这里,我们获取文档中所有 <p> 元素的列表,这些元素的直接父元素是带有 "highlighted" 类的 <div>,并且位于 ID 为 "test" 的容器内。
const container = document.querySelector("#test");
const matches = container.querySelectorAll("div.highlighted > p");
此示例使用属性选择器来返回文档中包含名为 "data-src" 属性的 <iframe> 元素的列表。
const matches = document.querySelectorAll("iframe[data-src]");
这里,一个属性选择器用于返回一个列表中包含的列表项的列表,该列表的 ID 为 "user-list",并且具有 "data-active" 属性,其值为 "1"。
const container = document.querySelector("#user-list");
const matches = container.querySelectorAll("li[data-active='1']");
访问匹配项
一旦返回了匹配元素的 NodeList,您就可以像访问任何数组一样检查它。如果数组为空(即其 length 属性为 0),则未找到匹配项。
否则,您可以使用标准数组符号访问列表内容。您可以使用任何常见的循环语句,例如:
const highlightedItems = userList.querySelectorAll(".highlighted");
highlightedItems.forEach((userItem) => {
  deleteUser(userItem);
});
注意: NodeList 不是一个真正的数组,也就是说它没有 slice、some、map 等数组方法。要将其转换为数组,请尝试 Array.from(nodeList)。
选择器范围
querySelectorAll() 方法将其选择器应用于整个文档:它们不限定于调用该方法的元素。要限定选择器,请在选择器字符串的开头包含 :scope 伪类。
HTML
在此示例中,HTML 包含
- 两个按钮:#select和#select-scope
- 三个嵌套的 <div>元素:#outer、#subject和#inner
- 一个 <pre>元素,示例用它来输出。
<button id="select">Select</button>
<button id="select-scope">Select with :scope</button>
<div id="outer">
  #outer
  <div id="subject">
    #subject
    <div id="inner">#inner</div>
  </div>
</div>
<pre id="output"></pre>
JavaScript
在 JavaScript 中,我们首先选择 #subject 元素。
当按下 #select 按钮时,我们在 #subject 上调用 querySelectorAll(),并将 "#outer #inner" 作为选择器字符串。
当按下 #select-scope 按钮时,我们再次在 #subject 上调用 querySelectorAll(),但这次我们将 ":scope #outer #inner" 作为选择器字符串。
const subject = document.querySelector("#subject");
const select = document.querySelector("#select");
select.addEventListener("click", () => {
  const selected = subject.querySelectorAll("#outer #inner");
  output.textContent = `Selection count: ${selected.length}`;
});
const selectScope = document.querySelector("#select-scope");
selectScope.addEventListener("click", () => {
  const selected = subject.querySelectorAll(":scope #outer #inner");
  output.textContent = `Selection count: ${selected.length}`;
});
结果
当我们按下“选择”时,选择器会选择所有 ID 为 inner 且其祖先 ID 为 outer 的元素。请注意,即使 #outer 位于 #subject 元素之外,它仍然用于选择,因此我们的 #inner 元素被找到。
当我们按下“带 :scope 选择”时,:scope 伪类将选择器范围限制为 #subject,因此 #outer 不用于选择器匹配,我们找不到 #inner 元素。
转义属性值
此示例显示,如果 HTML 文档包含的 id 不是有效的 CSS 标识符,则在使用它在 querySelectorAll() 中之前,我们必须转义属性值。
HTML
在以下代码中,一个 <div> 元素的 id 是 "this?element",它不是一个有效的 CSS 标识符,因为 CSS 标识符中不允许使用 "?" 字符。
我们还有三个按钮和一个用于记录错误的 <pre> 元素。
<div id="container">
  <div id="this?element"></div>
</div>
<button id="no-escape">No escape</button>
<button id="css-escape">CSS.escape()</button>
<button id="manual-escape">Manual escape</button>
<pre id="log"></pre>
CSS
div {
  background-color: blue;
  margin: 1rem 0;
  height: 100px;
  width: 200px;
}
JavaScript
所有三个按钮在点击时都会尝试选择 <div>,然后将其背景颜色设置为随机值。
- 第一个按钮直接使用 "this?element"值。
- 第二个按钮使用 CSS.escape()来转义该值。
- 第三个按钮使用反斜杠明确转义 "?"字符。请注意,我们还必须使用另一个反斜杠来转义反斜杠本身,例如:"\\?"。
const container = document.querySelector("#container");
const log = document.querySelector("#log");
function random(number) {
  return Math.floor(Math.random() * number);
}
function setBackgroundColor(id) {
  log.textContent = "";
  try {
    const elements = container.querySelectorAll(`#${id}`);
    const randomColor = `rgb(${random(255)} ${random(255)} ${random(255)})`;
    elements[0].style.backgroundColor = randomColor;
  } catch (e) {
    log.textContent = e;
  }
}
document.querySelector("#no-escape").addEventListener("click", () => {
  setBackgroundColor("this?element");
});
document.querySelector("#css-escape").addEventListener("click", () => {
  setBackgroundColor(CSS.escape("this?element"));
});
document.querySelector("#manual-escape").addEventListener("click", () => {
  setBackgroundColor("this\\?element");
});
结果
点击第一个按钮会报错,而第二个和第三个按钮则正常工作。
规范
| 规范 | 
|---|
| DOM # ref-for-dom-parentnode-queryselectorall① | 
浏览器兼容性
加载中…