jQuery .attr() vs .prop()
10 Sep 2017本文筆記 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 個重點
- 取值和設值。
- 初始值與目前狀態是否相符。
- Attribute 與 Property 並不同步。
取值和設值
取值方面來說,若元素有設定 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(註 3)
$('.checkbox-3').attr('checked'); //checked
註 3 雖然在 HTML 特性上設定 checked 的值為 false,但 checkbox 仍為勾選狀態,prop 為 true 且 attr 為 checked。在 HTML5 規範說明得很清楚,只要 attribute 出現,就是勾選,若不要勾選就不要設定。
設值方面來說,由於 .attr()
只要有設定 HTML 特性 checked,不論等號後面的值是什麼,甚至不帶值,皆會得到 checked,意即只要設定特性名稱即可。若要取消勾選則要使用 .removeAttr()
移除該特性。.prop()
仍是使用布林值設定勾選與否。
初始值與目前狀態是否相符
- Attribute 永遠都是呈現初始值(同註 3),與目前狀態無關,因此檢視 HTML 原始碼時是看不出變化的。
- Property 會反映目前狀態。
範例在這裡。
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];