淺談 HTML 的 data-* 屬性應用:組陣列、用 dataset 取值
在 HTML 結構中會看到很多標籤,h1, h2, p…,但你可曾想過,這些標籤跟著的屬性(attribute),它的功能是什麼嗎?其實屬性的功能都是在補充與這些 HTML 標籤有關的更多資訊!
既然屬性是 HTML 標籤的補充資料,那想當然爾,這些資料必定有它的用處,而其中當要自定義資料的時候,會使用 data-* 這個屬性來儲存開發者所需的資料,但問題是,到底要怎麼取用到這些標籤上的資料?這些資料又能怎麼用?是本文想探討的問題。
全域屬性
在研究 data-* 的取得方式和用法前,先來看看 HTML 元素上有哪些全域屬性吧。
什麼是全域屬性?在 HTML 標籤上可能可以帶入很多屬性,而這些屬性裡面也有分全域屬性,以及在特定的元素上才能使用的屬性 (也就是非全域屬性)。全域屬性是在全部的標籤上都能共用的屬性,例如:
全域屬性:class, id, style, data-* ...<h1 class="main-title">我是個主標</h1><h2 id="another-title">我是另一個title</h2><p style="color: red;">我是個段落</p><div data-year="2021">今年是西元 2021 年</div>
既然有全域屬性,當然也就有一些屬性是在特定的標籤上才能使用的,例如:
僅對特定標籤有作用的屬性:href, type, autoplay...<a href="#">一個連結</a><link href="#"><button type="button"></button><input type="text"><video autoplay="false"></video>
上述的所有標籤屬性,列出來只是要說明屬性與 HTML 元素之間是如何互相搭配應用的,由於屬性真的是太多了,大概七天七夜也看不完,但本文會比較想討論的是全域屬性中的 data-* 屬性。
前面可看到屬性的功能都已經定下來了,但 data-* 屬性卻是能依照開發者自己所需要的資料來做設定的屬性,目的是方便開發過程中,可依照自己的需求在 data-* 屬性上面埋資料。
但問題是, data-* 屬性到底可以怎麼用呢?
舉例來說:
現在有兩個 p 標籤上設定 data-user 屬性 (屬性要設定成什麼,由開發者自己定義),其值分別為 “信箱” 跟 “密碼”。
//HTML
<p class="alertMsg" data-user="信箱"></p>
<p class="alertMsg" data-user="密碼"></p>
以上述 HTML 為例,可以把這個問題分成三大部分來看:
(1) 如何選取 data-user 屬性?
- querySelectorAll + class選取器。
- querySelectorAll + 屬性選取器 (因為 data-* 是屬性)。
(2) 如何取到 data-user 屬性的值?
用 forEach 把兩個標籤都帶入,運用 dataset.user 取到值 (即:物件取值)。
(3) 取到的值,如何渲染到畫面上?
綁定 DOM,用 forEach 把多個字串資料 用 textContent / innerHTML 渲染到畫面上。
根據以上,首先第一步,透過 querySelectorAll 來選取 data-user 屬性:
(1) querySelectorAll + class 選取器用法 (只取一個 data-user)
const data = document.querySelectorAll('.alertMsg')[0];
// 用 ('.alertMsg')[0]:只選到 user="信箱"(2) querySelectorAll + 屬性選取器用法 (取到所有 data-user)
const data = document.querySelectorAll("[data-user]");
// 用 querySelectorAll("[data-user]")
// 選 到data-user="信箱"、data-user="密碼"
第二步,由於 querySelectorAll 會回傳陣列資料,因此可以開始用 forEach 來跑資料、取值:
const data = document.querySelectorAll("[data-user]");data.forEach(function(item){console.log(item)
// <p class="alertMsg" data-user="信箱"></p>
// <p class="alertMsg" data-user="密碼"></p>console.log(item.dataset)
// 取到 {user: "信箱"}, {user: "密碼"}console.log(item.dataset.user)
// 終於取到 "信箱"、"密碼"})
第三步,將 item.dataset.user 取出的值,賦予到 item 上,如此一來, forEach 每跑一次,就同步會把字串在畫面上劃入一次資料。
const data = document.querySelectorAll("[data-user]");let str = ''data.forEach(function(item){str = item.dataset.user;item.textContent = str;})
總結以上,本篇文章主要在整理 HTML 標籤與屬性之間的關係,透過更了解屬性,可以理解 data-* 屬性的功能,更進一步探討如何透過在 HTML 標籤上設定 data-* 屬性,埋入我們所需要的資料,再透過 dataset 將屬性中的值取出,並組出陣列透過 forEach 再依序將這些值渲染到畫面上。
由於能用陣列來跑 forEach 的關係,data-* 屬性在應用上,還能夠用陣列的 index 值來寫刪除資料的功能,詳細說明可以參考 JavaScript 初心者筆記: HTML 的自訂資料屬性 — data-*。
此外,也能夠透過綁定監聽事件,用 e.target.dataset,進一步與網頁互動、取到開發者想要取得的值,詳細可參閱 codepen 的用法。