Home
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

4

Local AI

--

Uedu Code

--

Taipei AQI 57 · Taichung AQI 74 · Tainan AQI 63 · Kaohsiung AQI 64
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 16

屬性、自訂資料與樣式

getAttribute、dataset、classList 與 style
Interaction 20 minute(s)

Learning Objectives

  • 讀寫元素節點的常用屬性:id、className、innerHTML、textContent,以及 nodeType、nodeName、parentNode、childNodes
  • 用 hasAttribute、getAttribute、setAttribute、removeAttribute 操作 HTML 屬性,並分辨 HTML 屬性(attribute)與 DOM 屬性(property)
  • 用 data-* 與 dataset 存放自訂資料,用 classList 新增、移除與切換 class
  • 用 style 修改行內樣式,用 getComputedStyle 讀取元素最後套用的樣式

元素身上帶著哪些資訊

上一課學會了找到元素、建立元素。這一課要處理找到之後的事:讀取與修改元素身上的資訊。

一個元素帶著三類資訊,這一課依序介紹:

資訊 例子 怎麼操作
節點本身的屬性 標籤名稱、父節點、子節點、文字內容 nodeName、parentNode、childNodes、textContent
HTML 標籤上的屬性 href、disabled、data-price getAttribute、setAttribute、dataset
樣式 顏色、寬度、class classList、style、getComputedStyle

DOM 樹裡的每一個東西都是節點:document 是文件節點,每個 HTML 標籤是元素節點,標籤裡的文字是文字節點, 標籤上的 id="main" 這類屬性則是屬性節點。

節點的常用屬性

屬性 意思
el.id 元素的 id
el.className 元素的 class(整串字串,例如 'card big')
el.innerHTML 元素裡的所有內容,包含 HTML 標籤
el.textContent 元素裡的純文字,標籤會被去掉
node.nodeType 節點類型的數字:元素是 1、文字是 3、document 是 9(屬性節點是 2)
node.nodeName 元素是大寫的標籤名稱('DIV')、文字節點一律是 '#text'、document 是 '#document'
node.nodeValue 文字節點是它的文字;元素節點與 document 是 null
node.parentNode 父節點
node.childNodes 所有子節點,包含文字節點(下一課會再比較它與 children)

以 <div id="main" class="card">Hello <b>Uedu</b></div> 為例:

  • main.innerHTML 是 'Hello <b>Uedu</b>',main.textContent 是 'Hello Uedu'
  • main.childNodes 有兩個子節點:文字節點 'Hello ' 與元素節點 <b>
  • main.firstChild.nodeName 是 '#text',main.firstChild.nodeValue 是 'Hello '

互動練習:節點的屬性

範例先印出了 id、textContent 與 innerHTML,比較後兩行的差別。接著依任務在 JavaScript 分頁最後面寫程式,按「執行」,看主控台與右邊 DOM 樹的變化。

想一想:節點的屬性

1.

<p id="p">你好,<em>同學</em></p> 中,p.innerHTML 與 p.textContent 分別是什麼?

2.

document.querySelector('p').nodeName 的值是什麼?

3.

元素原本是 class="card big",執行 el.className = 'title' 之後,class 變成什麼?

第 1 次作答

讀寫 HTML 屬性

寫在 HTML 標籤上的 href、value、disabled、target 等,叫做 HTML 屬性(attribute)。操作它們用下面幾個方法:

方法 作用
el.hasAttribute('href') 有沒有這個屬性,回傳 true/false
el.getAttribute('href') 讀取屬性值(一律是字串);沒有這個屬性回傳 null
el.setAttribute('target', '_blank') 設定屬性;已經有就更新值,沒有就新增
el.removeAttribute('disabled') 移除屬性
el.attributes 元素上所有屬性的集合

HTML 屬性與 DOM 屬性不一樣。瀏覽器建立元素物件時,會把大部分 HTML 屬性對應成物件上的屬性(property), 例如 link.href、input.value、button.disabled。兩者多數時候同步,但有幾個差別要記得:

情況 HTML 屬性 getAttribute(…) DOM 屬性 el.…
使用者在輸入框打字之後 getAttribute('value') 還是初始值 input.value 是目前的內容
<a href="/codelab"> '/codelab'(原本寫的字串) 完整網址,例如 'https://uedu.tw/codelab'
名稱不同 class、for className、htmlFor
布林屬性 disabled ''(只要屬性存在就生效) true/false

布林屬性有一個常見的陷阱:setAttribute('disabled', 'false') 仍然是停用,因為只要屬性存在就生效。 要啟用按鈕,請用 button.disabled = false 或 button.removeAttribute('disabled')。

互動練習:新增、修改與移除屬性

頁面上有一個連結、一個輸入框與一個停用的按鈕。依任務修改 JavaScript,按「執行」,右邊 DOM 樹會顯示每個元素目前的 HTML 屬性。

自訂資料 data-* 與 classList

自訂屬性:需要把資料放在元素上(商品價格、資料庫編號)時,HTML 規定用 data- 開頭的屬性。 JavaScript 從 el.dataset 讀寫,名稱去掉 data-,連字號後面的字母改成大寫(駝峰式):

HTML JavaScript
data-price="120" el.dataset.price(值是字串 '120',計算前要用 Number() 轉換)
data-user-id="7" el.dataset.userId
執行 el.dataset.status = 'sold' 元素上出現 data-status="sold"

setAttribute('target', 'test') 也能加上任何名稱的屬性,但自己發明的名稱可能與未來的 HTML 屬性衝突,自訂資料請用 data-*。

classList:className 會整串覆蓋,classList 則一次只處理一個 class,其他 class 不受影響:

方法 作用
el.classList.add('highlight') 加上 class(已經有就不重複加)
el.classList.remove('highlight') 拿掉 class
el.classList.toggle('on') 有就拿掉、沒有就加上;回傳執行之後有沒有這個 class
el.classList.contains('on') 有沒有這個 class,回傳 true/false

外觀的變化(顏色、邊框)建議寫在 CSS 的 class 裡,JavaScript 只負責加上、拿掉 class。這樣樣式集中在 CSS,比較好維護。

互動練習:dataset 與 classList

兩張商品卡片用 data-price、data-stock 記錄價格與庫存。依任務修改 JavaScript,按「執行」,看 DOM 樹上的 data-* 屬性與 class 怎麼改變。

想一想:屬性、dataset 與 classList

1.

使用者把輸入框(HTML 是 <input id="n" value="Amy">)的內容改成 Ben 之後,n.getAttribute('value') 與 n.value 分別是什麼?

2.

元素是 <li data-user-id="7">,在 JavaScript 裡怎麼讀到 7?

3.

按鈕目前沒有 on 這個 class,連續執行兩次 btn.classList.toggle('on') 之後,btn.classList.contains('on') 是什麼?

4.

要讓 <button id="b" disabled> 變成可以按,下列哪一個寫法沒有效果?

第 1 次作答

修改與讀取樣式

修改樣式:el.style 對應元素的 style="…" 行內樣式。CSS 屬性名稱有連字號的,改成駝峰式:

h1.style.color = 'red';                    // color
main.style.backgroundColor = 'blue';       // background-color
main.style.setProperty('font-size', '20px');            // setProperty 用 CSS 原本的名稱
main.style.setProperty('color', 'red', 'important');    // 第三個參數可以加上 !important

el.setAttribute('style', 'height: 100px') 也能設定,但會整段覆蓋原本的行內樣式;其他寫法一次只改一個屬性。

讀取樣式:el.style.width 只讀得到行內樣式,寫在 CSS 檔或 <style> 裡的樣式讀不到(是空字串)。 要知道元素最後實際套用的樣式,用 getComputedStyle:

const cs = window.getComputedStyle(main);   // 第二個參數可以傳 '::before' 這類偽元素,不需要時省略
console.log(cs.width);                       // '200px'
console.log(cs.getPropertyValue('background-color'));   // 'rgb(238, 242, 246)'

getComputedStyle 回傳的是計算後的值:顏色一律是 rgb(…)、長度一律是 px,而且唯讀,要改樣式還是用 el.style。

常用的樣式屬性:width、height、border、margin、padding、textAlign、color、backgroundColor、display。 同時要改好幾個樣式時,建議寫成 CSS 的 class,再用 classList 切換。

互動練習:style 與 getComputedStyle

#main 的寬度、內距與背景寫在 CSS 分頁裡。範例先印出 main.style.width,結果是空字串。依任務修改 JavaScript,按「執行」。

想一想:樣式

1.

CSS 檔裡寫了 #box { color: green; },元素沒有 style 屬性,box.style.color 會得到什麼?

2.

要把元素的 CSS background-color 改成黃色,下列哪一個寫法正確?

第 1 次作答

重點精華回顧

  • 節點的常用屬性:id、className、innerHTML(含標籤)、textContent(純文字)、nodeType(元素 1、文字 3)、nodeName(元素是大寫標籤名稱、文字是 #text)、parentNode、childNodes。
  • HTML 屬性用 hasAttribute、getAttribute、setAttribute、removeAttribute 操作;getAttribute 讀到的是原本寫的字串,DOM 屬性(input.value、link.href)是目前的狀態。
  • 布林屬性(disabled、checked)只要存在就生效,要取消請移除屬性或設成 false。
  • 自訂資料用 data-*,JavaScript 從 dataset 讀寫,名稱改成駝峰式,值一律是字串。
  • 切換 class 用 classList 的 add、remove、toggle、contains,不會影響其他 class;className 會整串覆蓋。
  • el.style 修改與讀取行內樣式(屬性名稱用駝峰式);getComputedStyle(el) 讀取最後實際套用的樣式,顏色是 rgb(…)、長度是 px。
這一課完成了!
Next lesson:DOM 元素集合
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。