Skip to content

DOM 選取教學:querySelector 與 getElementById 用法

DOM 的選取:querySelector 與 getElementById

想要順利的選取到 DOM,首先必須知道父、子層之間的關係。如下:

<ul> 的視角來看:

  • <h2>:兄弟。
  • <section>:父層。
  • <li>:子層。

只要了解元素之間的關係,就可以使用不同的方法來選取目標節點(Node)。

html
<section>
  <h2>Hello JavaScript!</h2>
  <ul>
    <li>直譯式語言。</li>
    <li>變數自動轉型。</li>
    <li>弱型別。</li>
  </ul>
</section>

五種方法速查

方法依據回傳找不到時
getElementById()id單一元素null
getElementsByTagName()標籤名稱HTMLCollection空集合
getElementsByClassName()類別名稱HTMLCollection空集合
querySelector()CSS 選取器第一個符合的元素null
querySelectorAll()CSS 選取器NodeList空集合

getElementById(id)

首先,必須確定 HTML 中,元素 id 在指定時必須是唯一的。

參數

id

id 是一個區分大小寫的字串,在 HTML 中是唯一的;只有一個元素應該具有任何給定的 id

回傳值

指定元素與 id 匹配的 DOM 元素,若匹配不到,則會回傳 null

注意

  • id 名稱是區分英文大小寫的,因此,必須完全正確才會運作。
  • id 名稱須保持唯一性。若有多個相同的 id 出現,僅會回傳第一個找到的元素。
html
<header class="header" id="Header">
  <h1 class="header__title">專注於網頁設計教學的補習班</h1>
  <p class="header__desc">
    12 年來協助 2
    萬多名學員提昇設計相關技術,成為視覺設計師、網頁設計師與前端工程師。
  </p>
</header>
js
console.log(document.getElementById('Header'));

getElementsByTagName(name)

搜尋整份 HTML,回傳匹配的指定元素名稱,且有可能是多個。其特性為 HTMLCollection,也有人稱為 類陣列

小提醒

回傳的對象是個 HTMLCollection(集合),且帶有即時特性,這也代表它能自動更新與 DOM Tree 保持同步。

參數

name

元素的名稱,例如:lipdiv

回傳值

找到匹配的對象後,會依照 DOM Tree 的順序回傳。若匹配不到,則會回傳 HTMLCollection []

html
<footer class="footer">
  <div class="container mx-auto footer__cntr">
    <h3 class="footer__name">
      <a href="javascript:;" target="_blank">圈圈叉叉有限公司</a>
    </h3>
    <ul class="footer__list">
      <li class="footer__item">電話:(02)2882-5252</li>
      <li class="footer__item">地址:台北市中正區鄭州路 8 號</li>
      <li class="footer__item">信箱:service@ooxx.com.tw</li>
      <li class="footer__item">營業時間:下午 2 點 ~ 晚上 10 點</li>
    </ul>
  </div>
</footer>
js
console.log(document.getElementsByTagName('li'));

getElementsByClassName(names)

搜尋整份 HTML,回傳匹配的指定類別名稱,且有可能是多個。其特性為 HTMLCollection,也有人稱為 類陣列

參數

names

匹配的類別名的字串;多個類別名稱之間以 space 分隔,可以回傳同時具備多個類別名稱的元素。

回傳值

指定元素與類別匹配的 DOM 元素。若匹配不到,則會回傳 HTMLCollection []

注意

這裡傳入的是 類別名稱,不是 CSS 選取器,所以寫 card 而不是 .card。要用選取器語法請改用 querySelectorAll()

html
<section class="card">
  <h2 class="card__title">Dreamweaver & CSS網頁設計教學課程</h2>
  <img class="card__img" src="./images/dw.png" alt="">
  <p class="card__desc">
    本課程是基礎的網頁設計入門教學,與 Photoshop
    的整合,本課程不是只軟體的操作,更強調設計、網站設計的結構、網頁版面的設計、網頁配色的設計、HTML語法、CSS語法...
  </p>
</section>
<section class="card">
  <h2 class="card__title">illustrator 平面設計教學與插畫設計課程</h2>
  <img class="card__img" src="./images/ai.png" alt="">
  <p class="card__desc">
    本課程將從最基本的工具操作、平面設計、插畫設計、icon 設計、logo
    設計、印刷排版...講起,課程內將有大量的範例讓您實際操作,因此沒有學過
    illustrator 的也可以參加喔...
  </p>
</section>
js
console.log(document.getElementsByClassName('card'));

querySelector(selector)

採用 CSS 選取器的方式進行 DOM 的匹配。

參數

selector

包含一個或多個要匹配的選取器字串。

回傳值

指定 CSS 選取器匹配的第一個 DOM 元素。若匹配不到,則會回傳 null

html
<header class="header" id="Header">
  <h1 class="header__title">專注於網頁設計教學的補習班</h1>
  <p class="header__desc">
    12 年來協助 2
    萬多名學員提昇設計相關技術,成為視覺設計師、網頁設計師與前端工程師。
  </p>
</header>
js
console.log(document.querySelector('#Header'));

querySelectorAll(selectors)

採用 CSS 選取器的方式進行 DOM 的匹配。其特性為 NodeList,也有人稱為 類陣列

參數

selectors

可匹配多個不同類型的 CSS 選取器,CSS 選取器之間用 , 做分隔。

回傳值

指定元素與類別匹配的 DOM 元素。若匹配不到,則會回傳 NodeList []

html
<section class="card">
  <h2 class="card__title">Dreamweaver & CSS網頁設計教學課程</h2>
  <img class="card__img" src="./images/dw.png" alt="">
  <p class="card__desc">
    本課程是基礎的網頁設計入門教學,與 Photoshop
    的整合,本課程不是只軟體的操作,更強調設計、網站設計的結構、網頁版面的設計、網頁配色的設計、HTML語法、CSS語法...
  </p>
</section>
<section class="card">
  <h2 class="card__title">illustrator 平面設計教學與插畫設計課程</h2>
  <img class="card__img" src="./images/ai.png" alt="">
  <p class="card__desc">
    本課程將從最基本的工具操作、平面設計、插畫設計、icon 設計、logo
    設計、印刷排版...講起,課程內將有大量的範例讓您實際操作,因此沒有學過
    illustrator 的也可以參加喔...
  </p>
</section>
js
console.log(document.querySelectorAll('.card, .card__title'));

HTMLCollection 與 NodeList

兩者都是 類陣列:能用索引取值、有 length,但沒有完整的陣列方法。差別在這裡:

項目HTMLCollectionNodeList
由誰回傳getElementsBy 系列querySelectorAll()
是否即時更新是,DOM 變動會同步否,是當下的快照
可否直接 forEach()不可

需要用到 map()filter() 這類陣列方法時,先轉成真正的陣列:

js
const cards = document.getElementsByClassName('card');

// 方法一:Array.from
Array.from(cards).forEach((card) => console.log(card));

// 方法二:展開運算子
[...cards].forEach((card) => console.log(card));

把選取結果存進變數

同一個元素若要用很多次,請先存進變數,別每次都重新查詢整份文件:

js
const elemBox = document.querySelector('#Box');

elemBox.textContent = '我是內容';
elemBox.classList.add('is-active');

這個習慣在 一些常用的小技巧節點的屬性 會一直看到。

常見問題

querySelector 與 getElementById 該用哪一個?

兩者都可以。querySelector() 用 CSS 選取器語法,寫法統一、能表達複雜條件;getElementById() 只認 id、速度略快。實務上多數專案為了一致性會統一用 querySelector()

HTMLCollection 與 NodeList 有什麼差別?

getElementsBy 系列回傳 HTMLCollection,具即時特性,DOM 變動時內容會自動更新;querySelectorAll() 回傳的 NodeList 是靜態快照,且可以直接使用 forEach()

選取不到元素時會回傳什麼?

getElementById()querySelector() 回傳 nullgetElementsBy 系列回傳空的 HTMLCollectionquerySelectorAll() 回傳空的 NodeList。後兩者不是 null,判斷有沒有選到要看 length

為什麼 getElementsByClassName 不用加點?

因為它的參數是類別名稱本身,不是 CSS 選取器,寫 card 即可。只有 querySelector()querySelectorAll() 才需要寫成 .card 這種選取器語法。

同一個元素會重複選取很多次,該怎麼處理?

把選取結果先存到變數裡再重複使用。每次呼叫選取方法都要重新查詢整份文件,存進變數後直接從記憶體取用,程式也更好讀。

延伸閱讀