JS中attribute和property的區別

property 和 attribute很是容易混淆,兩個單詞的中文翻譯也都很是相近(property:屬性,attribute:特性),但實際上,兩者是不一樣的東西,屬於不一樣的範疇。html

  • property是DOM中的屬性,是JavaScript裏的對象;
  • attribute是HTML標籤上的特性,它的值只可以是字符串;

attribute和property介紹

簡單理解,Attribute就是dom節點自帶的屬性,例如html中經常使用的id、class、title、align等。瀏覽器

而Property是這個DOM元素做爲對象,其附加的內容,例如childNodes、firstChild等。dom

有如下代碼:測試

<div id="div1" class="divClass" title="divTitle" title1="divTitle1"></div> var in1=document.getElementById("div1"); console.log(in1);

對於id爲div1的div,它的property內容以下:(部分)spa

能夠發現有一個名爲「attributes」的屬性,類型是NamedNodeMap,同時有「id」和「className」、」title「等基本的屬性,但沒有「titles」這個自定義的屬性。翻譯

console.log(in1.id);          //div1
    console.log(in1.className);        //divClass
    console.log(in1.title);          //divTitle
    console.log(in1.title1);       //undefined

能夠發現,標籤中的屬性,「id」和「className」、」title「會在in1上建立,而「titles」不會被建立。這是因爲,每個DOM對象都會有它默認的基本屬性,而在建立的時候,它只會建立這些基本屬性,咱們在TAG標籤中自定義的屬性是不會直接放到DOM中的。設計

那自定義的」title1「去哪裏了呢?在attributes屬性裏能夠看到以下:3d

「title1」被放在了attributes這個對象裏,這個對象按順序記錄了咱們在TAG中定義的屬性和屬性的數量。雙向綁定

從這裏就能夠看出,attributes是屬於property的一個子集,它保存了HTML標籤上定義屬性。若是再進一步探索attitudes中的每個屬性,會發現它們並非簡單的對象,它是一個Attr類型的對象,擁有NodeType、NodeName等屬性。關於這一點,稍後再研究。注意,打印attribute屬性不會直接獲得對象的值,而是獲取一個包含屬性名和值的字符串,如:code

console.log(in1.attibutes.title1);        // divTitle1

由此能夠得出:

  • HTML標籤中定義的屬性和值會保存該DOM對象的attributes屬性裏面;
  • 這些attribute屬性的JavaScript中的類型是Attr,而不只僅是保存屬性名和值這麼簡單;

再以下:

<input id="in_2">

在它的property中有以下部分:

儘管咱們沒有在TAG中定義「value」,但因爲它是DOM默認的基本屬性,在DOM初始化的時候它照樣會被建立。

「腳踏兩隻船」

經常使用的Attribute,例如id、class、title等,已經被做爲Property附加到DOM對象上,能夠和Property同樣取值和賦值。可是自定義的Attribute,就不會有這樣的特殊優待,例如:

<div id="div1" class="divClass" title="divTitle" title1="divTitle1">100</div>

這個div裏面的「title1」就不會變成Property。

即,只要是DOM標籤中出現的屬性(html代碼),都是Attribute。而後有些經常使用特性(id、class、title等),會被轉化爲Property。能夠很形象的說,這些特性/屬性,是「腳踏兩隻船」的。

最後注意:「class」變成Property以後叫作「className」,由於「class」是ECMA的關鍵字。

  • DOM有其默認的基本屬性,而這些屬性就是所謂的「property」,不管如何,它們都會在初始化的時候再DOM對象上建立。
  • 若是在TAG對這些屬性進行賦值,那麼這些值就會做爲初始值賦給DOM的同名property。

attribute和property的取值和賦值

一、attribute取值

《js高級程序設計》中提到,爲了方便操做,建議你們用setAttribute()和getAttribute()來操做便可。

<div id="div1" class="divClass" title="divTitle" align="left" title1="divTitle1"></div>
 
 var id = div1.getAttribute("id"); var className1 = div1.getAttribute("class"); var title = div1.getAttribute("title"); var title1 = div1.getAttribute("title1");   //自定義特性

getAttribute()能夠取得任何特性,不論是標準的仍是自定義的。

可是這個方法的瀏覽器兼容性有問題,有些瀏覽器可能會獲取屬性Property的值,所以jQuery要作一個測試,看getAttribute()是不是絕對獲取特性Attribute的值。

div1.className = 'a'; var judge = div1.getAttribute("className") === 'a';

若是以上代碼成立,說明getAttribute()方法出現了問題,將再也不使用。

二、attribute賦值

div1.setAttribute('class', 'a'); div1.setAttribute('title', 'b'); div1.setAttribute('title1', 'c'); div1.setAttribute('title2', 'd');

用setAttrbute()賦值,任何Attribute均可以,包括自定義的。並且,賦值的Attribute會馬上表現到DOM元素上。

若是是標準特性,也會更新它們關聯的屬性的值:

最後注意,setAttribute()的兩個參數,都必須是字符串。即對特性Attribute職能賦值字符串,而對屬性Property就能夠賦任何類型的值了。

三、property取值

屬性取值很簡單。取任何屬性的只,用「.」就能夠:

var id = div1.id; var className = div1.className; var childNodes = div1.childNodes; var attrs = div1.attributes;

此處再次強調:

  1. class特性在變成屬性時,名字改爲了「className」,所以div1.className和div1.getAttrbute('class')相同。
  2. 上面代碼中的div1.attributes是取的attributes這一屬性,取出來保存到attrs變量中,attrs就成了一個NamedNodeList類型的對象,裏面存儲了若干個Attr類型。

 4. Property賦值

賦值和基本的js對象屬性賦值同樣,用「.」便可:

div1.className = 'a'; div1.align = 'center'; div1.AAAAA = true; div1.BBBBB = [1, 2, 3];

對屬性Property能夠賦任何類型的值,而對特性Attribute只能賦值字符串!

另外,對於屬性Property的賦值在IE中可能會引發循環引用,內存泄漏。爲了防止這個問題,jQuery.data()作了特殊處理,解耦了數據和DOM對象。

 更改property和attribute其中一個值,會出現什麼結果

in1.value='new value of prop'; console.log(in1.value); // 'new value of prop'
console.log(in1.attributes.value);         // 'value="1"'

此時,頁面中的輸入欄的值變成了「new value of prop」,而propety中的value也變成了新的值,但attributes卻仍然是「1」。從這裏能夠推斷,property和attribute的同名屬性的值並非雙向綁定的。

若是反過來,設置attitudes中的值,效果會怎樣呢?

in2.setAttribute('value','ni') console.log(in2.value); //ni
    console.log(in2.attributes.value); //value='ni'

由此,可得出結論:

  • property可以從attribute中獲得同步;
  • attribute不會同步property上的值;
  • attribute和property之間的數據綁定是單向的,attribute->property;
  • 更改property和attribute上的任意值,都會將更新反映到HTML頁面中;
相關文章
相關標籤/搜索