js便籤筆記(2)——DOM元素的特性(Attribute)和屬性(Property)

王福朋發表於2014-03-28

1.介紹:

上篇js便籤筆記http://www.cnblogs.com/wangfupeng1988/p/3626300.html最後提到了dom元素的Attribute和Property,本文簡單介紹一下我的理解。

其實Attribute和Property這兩個單詞,翻譯出來都是“屬性”,《js高階程式設計》書中翻譯為“特性”和“屬性”,以示區別。

 

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

而Property是這個DOM元素作為物件,其附加的內容,例如childNodes、firstChild等:

 

2.“腳踏兩隻船”:

另外,常用的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的關鍵字。以下程式碼等價:

1 var className = div1.className;
2 var className1 = div1.getAttribute("class");

 

3.取值與賦值:

3.1. Attribute取值:

上一篇部落格http://www.cnblogs.com/wangfupeng1988/p/3626300.html已經提到,可以通過div1.Attributes獲取所有的特性資訊,div1.Attributes將返回一個NamedNodeList類陣列,其中包含了若干個Attr型別的物件。《js高階程式設計》中提到,為了方便操作,建議大家用setAttribute()和getAttribute()來操作即可。

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

getAttribute()可以取得任何特性,不管是標準的還是自定義的。

但是這個方法的瀏覽器相容性有問題,有些瀏覽器可能會獲取屬性Property的值,因此jQuery要做一個測試,看getAttribute()是否是絕對獲取特性Attribute的值。

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

如果以上程式碼成立,說明getAttribute()方法出現了問題,將不再使用。

3.2. Attribute賦值:

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

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

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

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

 

3.3. Property取值:

屬性取值很簡單。取任何屬性的只,用“.”就可以:

1 var id = div1.id;
2 var className = div1.className;
3 var childNodes = div1.childNodes;
4 var attrs = div1.attributes;

此處再次強調:

第一,class特性在變成屬性時,名字改成了“className”,因此div1.className和div1.getAttrbute('class')相同。

第二,上面程式碼中的div1.attributes是取的attributes這一屬性,取出來儲存到attrs變數中,attrs就成了一個NamedNodeList型別的物件,裡面儲存了若干個Attr型別。

 

3.4. Property賦值:

賦值和基本的js物件屬性賦值一樣,用“.”即可:

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

對屬性Property可以賦任何型別的值,而對特性Attribute只能賦值字串!

另外,對於屬性Property的賦值在IE中可能會引起迴圈引用,記憶體洩漏。為了防止這個問題,jQuery.data()做了特殊處理,解耦了資料和DOM物件,有興趣可以瞭解以下。這不是本文的重點,不做贅述。

 

4.style和onclick:

其實style和onclick與id、class、title一樣,也是“腳踏兩隻船”,但是向id、class、title都是簡單的字串值,用“.”和getAttribute()獲取結果一樣。但是對於style和onclick這兩者,就不一樣了。

4.1. 用“.”獲取Style:

<div id="div1" class="divClass" style="width:100%; padding:10px;">100</div>
console.log(div1.style);

以上程式碼中,返回了一個CSSStyleDeclaration物件,這個物件中包含著樣式的所有資訊:

 

4.2. 用getAttribute()獲取style:

<div id="div1" class="divClass" style="width:100%; padding:10px;">100</div>

console.log(div1.getAttribute("style"));

以上程式碼返回的就是一個簡單的字串:“width:100%; padding:10px;

 

4.3. 總結:

上面兩個例子,用“.”獲取的是style屬性Property,我們可以給屬性Property賦任何型別的值;而用getAttribute()獲取的是特性Attribute,特性Attribute中只能存貯字串。兩者的資料結構不一致,導致返回的結果不一致。

到這裡,我們就不需要再演示用“.”和getAttribute()獲取onclick了,大家猜想就能得到答案。。。

 

5.總結:

本文簡單介紹了DOM元素的特性(Attribute)和屬性(Property),下面說一說重點條目:

  • 特性和屬性兩者的儲存方式不同;
  • “2.腳踏兩隻船”要了解;
  • DOM屬性可能會導致迴圈引用記憶體洩漏。

 

就寫到這裡吧,大家覺得有需要補充的,儘管提出意見!

 

補充:對getAttributeNode()和setAttributeNode()的分析。

相關文章