一次搞懂 – attr 與 prop 的差別

Introduction

如果今天要透過程式把一個 checkbox 打勾,我必須承認,在我還沒搞懂 attr 與 prop 的差別之前,要使用他們,我都是直接「網頁開發人員工具」打開來,console 直接下指令,讀者不妨猜猜看,看到底是哪一種:

$(element).attr("checked", true);
$(element).attr("checked", "true");
$(element).attr("checked", "checked");
$(element).attr("checked", "");
$(element).prop("checked", true);

上述五種寫法,曾經「同時」在我的系統中運作著, 因為我維護的程式碼,是十年之間經過數十人協作過的。所以透過我的例子,你應該是真的可以「一次搞懂」。

差在哪?

 AttributeProperty
屬性HTML 文檔節點屬性Javascript element 物件屬性
屬性意義初始狀態實際狀態
屬性接受值字串 (若不是,會自動調用 toString())任何資料型態
javascript 取得/設定方法.getAttribute(“checked”)
.setAttribute(“checked”, “true”)
.checked
.checked=true
jQuery 取得/設定方法.attr(“checked”)
.attr(“checked”, “true”)
.prop(“checked”)
.prop(“checked”, true)
jQuery 版本1.0 之後可使用 .attr(),且 1.6 版以前兼職 .prop 的功能1.6 之後可使用 .prop()

練習一下

透過上面這張表格,你幾乎可以解掉九成的相關問題,比如

  • <input type=”checkbox” checked> 這邊的 checked 屬性指的是 attribute,因為是直接定義在 HTML 文檔節點上。
  • document.getElementById(element).checked = true; 這邊的 checked 屬性指的是 property,因為是抓到該元素的 DOM 節點之後,設定在物件上。
  • <form> 裡面的 reset 按鈕,會根據「初始狀態」來幫表單重置,因此要設定 attribute 才會有效。
  • 使用者操作完按下一步,我們要取得欄位目前「實際狀態」,因此要取得 property 才會有效。

請拿著這張表格,到我寫的 codepen 對應一下,你是不是能答對每個 checkbox 的 兩種屬性取出來是什麼樣子呢?

小提醒

雖然我說 attr 是設定初始狀態,但你可能會發現,如果先用 attr 設定完屬性,再用 prop 去取得屬性,會連 prop 都變成剛剛設定的屬性;反之,如果先用 prop 設定屬性,再用 attr 去取得屬性,attr 則完全不受影響。

原因比較深沉一些,不過大概就是,如果我們修改初始狀態,其實底層會同時幫我們修改實際狀態,但反之則不會。

這部分算是滿容易讓人混淆的,所以我個人不喜歡也不建議 attr 跟 prop 兩個針對同一個屬性混用,除非真的知道它背後的影響有哪些。

總結

如果上面那一堆劈哩趴啦,讓你的腦袋壓力太大的話,遵守以下幾點就可以了:

  1. 如果你的畫面一打開,就要有某個屬性,請用 attr,或者直接寫在 html 上也可以。
  2. 非上述的狀況,比如使用者操作過後,你想要取得屬性值,或者你需要動態修改屬性,通通用 prop。
  3. 基本上一般人使用 checked、disabled、selected、readonly 等,都是透過 prop 在取值或設定。

Reference

jQuery 1.6 attr v.s prop
jQuery attr v.s prop
從各面向看 attr v.s prop

Note

雖然最後才說有點欠打,但我其實認為,這兩者的差異真的很難用看的就看懂,因為我也是跌跌撞撞了很多次,終於下定決心搞懂它時,還費了不少時間到處查資料,在 console 試了非常多次,證明「畫面上顯示的」、「HTML 看到的」、「用 js 取得的」,三者都能如我所料,才終於來發這篇文。

如果有任何錯誤,再請你留言跟我指教或討論,我會非常感激的!

留個言吧!