Element: querySelectorAll() 方法

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

ElementquerySelectorAll() 方法返回一個靜態(非即時)的 NodeList,代表一個與指定選擇器組匹配的元素列表,這些元素是呼叫該方法的元素的後代。

語法

js
querySelectorAll(selectors)

引數

選擇器 (selectors)

一個包含一個或多個要匹配的選擇器的字串。該字串必須是有效的 CSS 選擇器字串;如果不是,將丟擲 SyntaxError 異常。

請注意,HTML 規範不要求屬性值是有效的 CSS 識別符號。如果 classid 屬性值不是有效的 CSS 識別符號,那麼在使用它作為選擇器之前,您必須對其進行轉義,可以透過對該值呼叫 CSS.escape(),或者使用 跳脫字元 中描述的一種技術。有關示例,請參見 轉義屬性值

選擇器應用於整個文件,而不僅僅是呼叫 querySelectorAll() 的特定元素。要將選擇器限制在呼叫 querySelectorAll() 的元素上,請在選擇器開頭包含 :scope 偽類。請參見 選擇器範圍 示例。

返回值

一個非即時 NodeList,其中包含一個 Element 物件,對應於每個匹配至少一個指定選擇器的後代節點。這些元素按文件順序排列——即父節點在子節點之前,較早的兄弟節點在較晚的兄弟節點之前。

注意:如果指定的 selectors 包含 CSS 偽元素,則返回的列表始終為空。

異常

SyntaxError DOMException

如果指定的 selectors 字串的語法無效,則丟擲。

示例

獲取所有具有自定義資料值的元素

此示例使用屬性選擇器來選擇多個具有包含“funnel-chart-percent”的 data-name 資料屬性的元素。

html
<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>
js
const refs = [
  ...document.querySelectorAll(`[data-name*="funnel-chart-percent"]`),
];

獲取匹配列表

要獲取元素 myBox 中包含的所有 <p> 元素的 NodeList

js
const matches = myBox.querySelectorAll("p");

此示例返回 myBox 中所有類為 notealert<div> 元素的列表

js
const matches = myBox.querySelectorAll("div.note, div.alert");

在這裡,我們獲取文件中所有 <p> 元素的列表,這些元素的直接父元素是帶有 "highlighted" 類的 <div>,並且位於 ID 為 "test" 的容器內。

js
const container = document.querySelector("#test");
const matches = container.querySelectorAll("div.highlighted > p");

此示例使用屬性選擇器來返回文件中包含名為 "data-src" 屬性的 <iframe> 元素的列表。

js
const matches = document.querySelectorAll("iframe[data-src]");

這裡,一個屬性選擇器用於返回一個列表中包含的列表項的列表,該列表的 ID 為 "user-list",並且具有 "data-active" 屬性,其值為 "1"

js
const container = document.querySelector("#user-list");
const matches = container.querySelectorAll("li[data-active='1']");

訪問匹配項

一旦返回了匹配元素的 NodeList,您就可以像訪問任何陣列一樣檢查它。如果陣列為空(即其 length 屬性為 0),則未找到匹配項。

否則,您可以使用標準陣列符號訪問列表內容。您可以使用任何常見的迴圈語句,例如:

js
const highlightedItems = userList.querySelectorAll(".highlighted");

highlightedItems.forEach((userItem) => {
  deleteUser(userItem);
});

注意: NodeList 不是一個真正的陣列,也就是說它沒有 slicesomemap 等陣列方法。要將其轉換為陣列,請嘗試 Array.from(nodeList)

選擇器範圍

querySelectorAll() 方法將其選擇器應用於整個文件:它們不限定於呼叫該方法的元素。要限定選擇器,請在選擇器字串的開頭包含 :scope 偽類。

HTML

在此示例中,HTML 包含

  • 兩個按鈕:#select#select-scope
  • 三個巢狀的 <div> 元素:#outer#subject#inner
  • 一個 <pre> 元素,示例用它來輸出。
html
<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" 作為選擇器字串。

js
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> 元素。

html
<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

css
div {
  background-color: blue;
  margin: 1rem 0;
  height: 100px;
  width: 200px;
}

JavaScript

所有三個按鈕在點選時都會嘗試選擇 <div>,然後將其背景顏色設定為隨機值。

  • 第一個按鈕直接使用 "this?element" 值。
  • 第二個按鈕使用 CSS.escape() 來轉義該值。
  • 第三個按鈕使用反斜槓明確轉義 "?" 字元。請注意,我們還必須使用另一個反斜槓來轉義反斜槓本身,例如:"\\?"
js
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①

瀏覽器相容性

另見