歡迎光臨
每天分享高質量文章

DOM中Property與Attribute的區別

作者:大搜車前端團隊部落格

網址:http://f2e.souche.com/blog/domde-attributehe-property/

property和attribute的漢語翻譯幾乎相同,都有“屬性”的意義(這裡姑且稱attribute為“特性”,以方便區分),而他們的取值也經常相同,但有時又會踩坑,發現二者會不相等,不同步。

0.奇葩的IE

本文開始之前不得不提一下萬惡之源IE,在IE<9中,瀏覽器會把所有的property和attribute強制對映,即property = attribute. (class特殊:className = class)。正因為IE<9中的這種對映誤導了很多人以為二者完全相同。

1. Property

每個DOM節點都是一個object物件,它可以像其他的js Object一樣具有自己的property和method,所以property的值可以是任何資料型別,大小寫敏感,原則上property應該僅供js操作,不會出現在html中(預設屬性除外:id/src/href/className/dir/title/lang等),和其他js object一樣,自定義的property也會出現在object的for…in遍歷中。

eg.

var list=[];

for(var key in document.body) {

list.push(key)

}

console.log(list.join(‘\n’));

2. Attribute

attribute出現在dom中,js提供了getAttribute/setAttribute等方法來獲取和改變它的值,attribute的值只能是字串且大小寫不敏感,最後作用於html中,可以影響innerHTML獲取的值。可以透過訪問dom節點的attributes屬性來獲取改節點的所有的attribute。(在IE<9中,attribute獲取和改變的實際上是property。)

3.自定義的Property與Attribute不同步,不相等

html:

js:

var test = document.getElementById(‘test’);

test.self = ‘selfProperty’;

console.log(test.self) => ‘selfProperty’

test.getAttribute(‘self’) => null

conclusion:自定義的property與自定義的attribute無同步關係

4.非自定義的DOM property與 attributes 是有條件同步的

非自定義的屬性(id/src/href/name/value等),透過setAttribute修改其特性值可以同步作用到property上,而透過.property修改屬性值有的(value)時候不會同步到attribute上,即不會反應到html上(除以下幾種情況,非自定義屬性在二者之間是同步的)。

  • 非自定義屬性(id/src/href/name/value等)未顯式定義在dom中才會時,初始的property與attribute不同

html:

初始值property: testvalue.value => “”

初始值attribute: testvalue.getAttribute(‘value’) => null

  • input:value/checked的單向同步關係透過setAttribute改變input的value/checked都會同步到property中,但是,一旦改變他們的property值,就打破同步機制

html:

property: testvalue.value => ‘sync’

attribute: testvalue.getAttribute(‘value’) => ‘sync’

testvalue.setAttribute(‘value’,’abc’) => ‘abc’

則屬性會同步: testvalue.value => ‘abc’

testvalue.value = ‘ddd’;

則同步機制失效: testvalue.getAttribute(‘value’) => ‘abc’

  • 同步不是複製,同步機制依舊,值不同(src/href)透過getAttribute獲取的是href/src的實際值,而點號(property)獲取的是完整的url。

html: a(id=”testHr” href=”/test/”)

property: testHr.href=”/blog/” => ‘http://f2e.souche.com/blog/’

attribute: testHr.getAttribute(‘href’) => ‘/blog/’

  • 非直接對映的同步,雖然同步了,但是同步後的屬性名字不同,或者取值方式不同:class/data-XX/styleclass對映成className

    data-XXX對映到 dataset.XXX,透過JQuery的attr,prop訪問時候不同步。

    style屬性不接受字串型賦值,只能透過style.XXX

html:

testvalue.getAttribute(‘class’) <=>testvalue.className

testvalue.setAttribute(‘style’,’color:red’) <=> testvalue.style.color

testvalue.getAttribute(‘data-id’)<=> testvalue.dataset.id

小結

property與attribute都是dom的核心功能,鑒於有的屬性上會出現單項同步的情況似乎attribute貌似更保險一點,以下是二者的關係表:

贊(0)

分享創造快樂