jQuery .attr() vs .prop()

本文筆記 Attribute 與 Property 的差異、jQuery 相關程式碼解析。

Attribute vs Property

Attribute 是 HTML 的特性,其值只能是字串(註 1);Property 是 DOM(Document Object Model,文件物件模型)的屬性,DOM(註 2)讓 document 能以物件的方式表示文件結構,因此 Property 可為任何值,例如:字串、布林或數字。以下表述之。

  Attribute Property
定義 HTML 的特性 DOM 的屬性
資料型別 字串 可為任何值

註 1 setAttribute() 會將設值轉為字串。

註 2 DOM(Document Object Model)是 HTML 和 XML 的程式介面,可藉此改變結構、樣式和內容。意即,HTML 和 XML 頁面的 API = DOM + Scripting Language(例如:JavaScript)。

範例

Attribute 與 Property 的差異對實際操作上有什麼影響呢?可歸結 3 個重點

取值和設值

取值方面來說,若元素有設定 HTML 特性 checked,則可用 .attr() 取得字串 checked ;若沒有設定,則會取到 undefined。若使用 .prop() 取該元素的屬性 checked 的值,則會取得布林值 true 或 false。

<input type="checkbox" class="checkbox-1" checked="true" />
<input type="checkbox" class="checkbox-2" />
<input type="checkbox" class="checkbox-3" checked="false" />
$('.checkbox-1').prop('checked'); //true
$('.checkbox-1').attr('checked'); //checked
$('.checkbox-2').prop('checked'); //false
$('.checkbox-2').attr('checked'); //undefined
$('.checkbox-3').prop('checked'); //true(註 2)
$('.checkbox-3').attr('checked'); //checked

註 3 雖然在 HTML 特性上設定 checked 的值為 false,但 checkbox 仍為勾選狀態,prop 為 true 且 attr 為 checked。在 HTML5 規範說明得很清楚,只要 attribute 出現,就是勾選,若不要勾選就不要設定。

設值方面來說,由於 .attr() 只要有設定 HTML 特性 checked,不論等號後面的值是什麼,甚至不帶值,皆會得到 checked,意即只要設定特性名稱即可。若要取消勾選則要使用 .removeAttr() 移除該特性。.prop() 仍是使用布林值設定勾選與否。

初始值與目前狀態是否相符

範例在這裡

jQuery 的 .attr() vs .prop()

以 3.2.1 版本為主,原始碼解析如下。

.attr()

使用 DOM 的 API setAttribute()getAttribute() 操作元素節點的特性。

Case 1:.attr(name, value) 設定 value 值

<input type="checkbox" class="checkbox-3" />
$('.checkbox-3').attr('checked', 'checked');

來看原始碼 line #7531。

elem.setAttribute( name, value + "" );

Case 2:.attr(name) 取得屬性值

$('.checkbox-3').attr('checked');

來看原始碼 line #7539 - 7542。

ret = jQuery.find.attr(elem, name);

return ret == null ? undefined : ret;

jQuery.find.attr 是來自於 line #1569 的 elem.getAttribute( name )

.prop()

Case 1:.prop(name, value) 設定 value 值

<input type="checkbox" class="checkbox-1" checked="true" />

執行這行程式碼。

$('.checkbox-1').prop('checked', true)

來看原始碼 line #7653。

return ( elem[ name ] = value );

這裡將 input.checkbox-1 的 checked 設為 true,並且回傳回去。意即

return document.getElementsByTagName[name] = value

Case 2:.prop(name) 取得屬性值

執行這行程式碼。

$('.checkbox-1').prop('checked')

來看原始碼 line #7660。

return elem[ name ];

這裡回傳 input.checkbox-1 的 checked 值,意即

return document.getElementsByTagName[name]

References


comments powered by Disqus