[譯]HTML attribute與DOM property之間的區別?

2dunn發表於2017-03-21

2018.3.1更:

有贊·微商城部門招前端啦,最近的前端hc有十多個,跪求大佬扔簡歷,我直接進行內推實時反饋進度,有興趣的郵件 lvdada#youzan.com,或直接微信勾搭我 wsldd225 瞭解跟多

有贊開源元件庫·zanUI


原文:http://joji.me/en-us/blog/html-attribute-vs-dom-property

當我們通過js處理DOM物件時非常容易將attribute(特性)property(屬性)混淆。document.getElementById('test').getAttribute('id')$('#test').attr('id'), document.getElementById('test').id還有$('#test').prop('id')三者都返回相同的id:“test”。這篇文章我將解釋attributeproperty的區別。

Attribute(特性)

  1. attribute特性由HTML定義,所有出現在HTML標籤內的描述節點都是attribute特性。
<div id="test" class="button" custom-attr="1"></div>
複製程式碼
document.getElementById('test').attributes;
// return: [custom-attr="hello", class="button",   id="test"]
複製程式碼
  1. attribute特性的型別總是字串型別。拿上邊的DIV為例,document.getElementById('test').getAttribute('custom-attr') 或者$('#test').attr('custom-attr')總是返回字串型別的"1"。

Property(屬性)

  1. property屬性屬於DOM物件,DOM實質就是javascript中的物件。我們可以跟在js中操作普通物件一樣獲取、設定DOM物件的屬性,並且property屬性可以是任意型別。
document.getElementById('test').foo = 1; // 設定屬性: foo 為 number型別: 1
document.getElementById('test').foo; // 獲取屬性值, return number: 1
$('#test').prop('foo'); // 使用jquery獲取屬性值, return number: 1
複製程式碼
$('#test').prop('foo', {
   age: 23,
   name: 'John'
}); // 使用jquery設定一個名為foo的物件
document.getElementById('test').foo.age; // return number型別: 23
document.getElementById('test').foo.name; // return string型別: "John"
複製程式碼

**譯者注:**這裡的property可以是任意型別指的是我們為DOM物件自定義新增的屬性,對於DOM物件的原始屬性,類似name屬性,無論我們設定什麼型別的值,最後返回的都是字元型別。

另外,我們獲取HTML5定義的data屬性時,獲取的值也是字串。<div data-id="33"></div>,ele.dataset.id // string 33

  1. 非自定義的attribute特性與property有1:1的對映關係,比如:id,class,title等。
<div id="test" class="button" foo="1"></div>
複製程式碼
document.getElementById('test').id; // return string: "test"
document.getElementById('test').className; // return string: "button"
document.getElementById('test').foo; // return undefined 因為foo是一個自定義的attr特性
複製程式碼

注意:當我們通過property屬性進行設定或獲取class時,我們需要使用**"className"**,因為在js中class是關鍵字。

**譯者注:**第二點的意思是說當我們在html中寫非自定義的attribute特性時,DOM物件會自動對映對應的property

  1. 非自定義的property(attribute)改變的時候,其對應的attribute(property)在多數情況下也會改變。
<div id="test" class="button"></div>
複製程式碼
	var div = document.getElementById('test');
   div.className = 'red-input';
   div.getAttribute('class'); // return string: "red-input"
   div.setAttribute('class','green-input');
   div.className; // return string: "green-input"
複製程式碼
  1. 當對應的property改變的時候,attribute特性value的值一直未預設值,並不會隨之改變。
<input id="search" value="foo" />
複製程式碼
var input = document.getElementById('search');
input.value = 'foo2';
input.getAttribute('value'); // return string: "foo"
複製程式碼

**譯者注:**這條特性意味著我們平時在寫業務的時候多數情況下使用property是正確的。當使用者input輸入更改的時候,attribute-value值不會變化,即使js更改value,也不會使attribute變化。這也驗證了第三點的。

  1. 最佳實踐

在javascript中我們推薦使用property屬性因為這個屬性相對attribute更快,更簡便。尤其是有些型別本該是布林型別的attribute特性。比如:"checked", "disabled", "selected"。瀏覽器會自動將這些值轉變成布林值傳給property屬性。

<input id="test" class="blue" type="radio" />
複製程式碼

好實踐

// get id
document.getElementById('test').id;
// set class
document.getElementById('test').className = 'red';
// get and set radio control status
document.getElementById('test').checked; // boolean 
document.getElementById('test').checked = true;
$('#test').prop('checked'); // boolean
$('#test').prop('checked', true);
複製程式碼

壞實踐

// get id
document.getElementById('test').getAttribute('id');
// set class
document.getElementById('test').setAttribute('class', 'red');
document.getElementById('test').getAttribute('checked'); //  返回字串型別 'checked'

複製程式碼

本文來自二口南洋,有什麼需要討論的歡迎找我。

相關文章