Vanilla JavaScript | Get DOM Elements 使用 JS 原生語法取得 DOM 元素


  1. 說明
    1. getElementById()
      1. 確認實際型別的方法
    2. getElementsByClassName()
    3. getElementsByTagName()
    4. QuerySelector()
    5. QuerySeletorAll()
  2. 應用情境
    1. 取得網頁上所有的連結
  3. 參考資料

筆記 JS 如何使用 JS 原生語法取得 DOM 元素,包含介紹 GetElementById, GetElementByName, QuerySelector, QuerySeletorAll ,並且介紹如何應用這些語法,提供將網頁上所有的 Anchor Link 擷取的解決方案 😎

JavaScript logo

說明

Template.html 是本次要練習 get element 的 DOM,此外 Template.html 有發佈於 GitHub 可以連結後使用 DevTools 進行實際操作。

實驗所使用的 Scripts GitHub Repo

Template.html

<body>
  <p id="p1">Lorem ipsum dolor sit amet consectetur adipisicing elit.
    <a id="a1" href="https://www.domain.local/Posts/Article?title=js">Link1</a>
  </p>
  <p>Earum atque distinctio itaque mollitia perspiciatis fuga vel voluptate molestias.
    <a id="a2" name="link" href="#link2">Link2</a>
    <a href="#link3">Link3</a>
  </p>
  <div class="footer">
    <p>Rerum vero dolore soluta culpa praesentium, mollitia voluptates?
      <a class="btn" name="link" href="#link4">Link4</a>
    </p>
    <a class="btn" id="a5" name="link" href="#link5">Link5</a>
  </div>
</body>

getElementById()

基本招式利用 element 的 Id 來指向 element,要注意的是如果 DOM 有重複的 Id,只會取到第一個相符 Id 的 element。

const tag = document.getElementById('a1');

tag 的型別為 HTMLAnchorElement

具有的 Properties 如表格的示範(以 #a1 tag 為例)

<a id="a1" href="https://www.domain.local/Posts/Article?title=js">Link1</a>
Property Example Inherit
innerHtml Link1 element.innerHTML
innerText Link1 HTMLElement.innerText
text Link1 Node.textContent
href https://www.domain.local/Posts/Article?title=js HTMLAnchorElement
hostname www.domain.local HTMLAnchorElement
pathname /Posts/Article HTMLAnchorElement
search ?title=js HTMLAnchorElement

確認實際型別的方法

Object.prototype.toString.call(variable)

getElementsByClassName()

這個方法是以元素的 Class Name 搜尋元素。

<div class="footer">
  <p>Rerum vero dolore soluta culpa praesentium, mollitia voluptates?
    <a class="btn" name="link" href="#link4">Link4</a>
  </p>
  <a class="btn" id="a5" name="link" href="#link5">Link5</a>
</div>
const htmlCollections = document.getElementsByClassName('btn');

htmlCollections.namedItem('a4')
// null

const tag_a_a5 = htmlCollections.namedItem('a5');
// link5

getElementsByTagName()

這個方法是以元素的 Tag Name 搜尋元素。

getElementsByClassName 及 getElementsByTagName 所回傳的都是 array-like 的 HtmlCollections Type,其只有 item* 及 namedItem Method,如果想要 loop 它的 elements 可以利用 Array.from 來處理。

使用 item Method 的差異在於使用索引子 (htmlCollections[0]) 的方式超過陣列範圍可能會發生 undefined,使用 item 不存在的 key 則會回報 null。

const htmlCollections = document.getElementsByTagName('a');

htmlCollections.length
// 5

htmlCollections.item(0)

Array.from(htmlCollections).forEach(item => {
    console.log(item);
});

QuerySelector()

QuerySelector 以及 QuerySelectorAll 支援 jQuery Selector like 的方式,也就是以 CSS Selector 的方式去指向 element,方便性遠勝原本只能使用 getElementByClassName 😏

const tag_a_link4 = document.querySelector('.btn')
// link4

QuerySeletorAll()

QuerySeletorAll 與 getElementsByClassName 及 getElementsByTagName 的差別在於回傳的型別為 NodeList,NodeList 相較於 HtmlCollections 提供了更多的 Method,例如 values 以及 entries。

const nodeList_btn = document.querySelectorAll('.btn')
// nodelist: a.btn, a#a5.btn

const nodeList_name_link = document.querySelectorAll('[name="link"]')
// nodelist: a#a2, a.btn, a#a5.btn

nodeList_btn.item(0)

for(let value of nodeList_btn.values()) {
    console.log(value);
}

for(let entry of nodeList_btn.entries()) {
    console.log(entry);
}

應用情境

取得網頁上所有的連結

const res = [];
document.querySelectorAll('a').forEach(
  aTag => res.unshift([aTag.text, aTag.href])
);
copy(res)

參考資料

Dcoument | MDN