Vanilla JavaScript | Get DOM Elements (get anchor and image with querySelector)
2021-08-09
筆記 JS 如何使用 JS 原生語法取得 DOM 元素,包含介紹 GetElementById, GetElementByName, QuerySelector, QuerySeletorAll ,並且介紹如何應用這些語法,提供將網頁上所有的 Anchor Link 擷取的解決方案 😎
說明
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)
取得所有連結並轉換為 Json Format
let linkList = [];
document.querySelectorAll('a').forEach(a => {
let href = a.getAttribute('href') || '';
let text = a.innerText.trim() || '[No Text]';
let className = a.getAttribute('class') || '';
href = decodeURIComponent(href);
linkList.push(`{"text": "${text}", "href": "${href}", "class": "${className}"}`);
});
copy('[' + linkList.join(',\n' ) + ']');
const newWindow = window.open('', '_blank');
newWindow.document.write('[' + linkList.join(',<br/>' ) + ']');
取得所有圖片並轉換為 Json Format
let imgList = [];
document.querySelectorAll('img').forEach(img => {
let src = img.getAttribute('src') || '[No src]';
let alt = img.getAttribute('alt') || '[No alt]';
src = decodeURIComponent(src);
imgList.push(`{"src": "${src}", "alt": "${alt}"}`);
});
copy('[' + imgList.join(',\n') + ']');
const newWindow = window.open('', '_blank');
newWindow.document.write('[' + imgList.join(',<br/>') + ']');