抛磚引玉
很多前端類庫(比如dojo與jquery)在涉及dom操作時都會見到兩個子產品:attr、prop。某天代碼複查時,見到一段為某節點設定文本的代碼:
這段代碼執行後并未生效,雖說innertext不是标準屬性,尚未被ff支援,可用的是chrome,這個屬性是被支援的。既然顯示的文本沒變,那就檢視一下元素吧。

innertext被添加到了html标簽上,而換成prop子產品後,成功的為節點替換文本。
以上的這個小案例就涉及到了dom操作時常常被忽略的一個問題:特性與屬性的差別
返本求源
在dom中,特性指的是html标簽上的屬性,比如:
property是對于某一類型特征的描述。可以這樣了解,在dom元素中可以通過點文法通路,又不是标準特性的都可以成為屬性。
dom中所有的節點都實作了node接口。node接口是在dom1級中定義的,其中定義了一些用來描述dom節點的屬性和操作方法。
常見的nodetype、nodevalue、節點關系(parentnode、childnodes、firstchild、lastchild、previoussibling、nextsibling等)都屬于node接口定義的屬性。對于node接口的具體實作者,htmlelement不僅繼承了這些屬性,還擁有五個wac規範中的五個标準特性:id、title、lang、dir、class和一個屬性:attributes。
每一個元素都有一個或多個特性,這些特性的用途是給出相應元素或其内容的附加資訊。通過dom元素直接操作特性的的方法有三個:
getattribute(attrname)
setattribute(attrname, value)
removeattribute(name)
這三個方法都可以操作自定義特性。但是隻有公認的(非自定義)特性才會以屬性的形式添加到dom對象中,以屬性方式操作這些特性會被同步到html标簽中。htmlelement的五個特性都有相應屬性與其對待:id、title、lang、dir、classname。在dom中以屬性方式操作這幾個特性會同步到html标簽中。
不過,html5規範對自定義特性做了增強,隻要自定義特性以"data-attrname"的形式寫入到html标簽中,在dom屬性中就可以通過element.dataset.attrname的形式來通路自定義特性,如:
元素的特性在dom中以attr類型來表示,attr類型也實作了node接口。attr對象有三個屬性:name、value、specified。其中,name是特性的名稱,value是特性值,specified是一個布爾值,用來訓示該特性是否被明确設定。
document.createattribute方法可以用來建立特性節點。例如,要為元素添加align特性可以使用如下方法:
要将新建立的特性添加到元素上,必須使用元素的setattributenode方法。添加特性後,特性會反映在html标簽上:
注意,盡管特性節點也實作了node接口,但特性卻不被認為是dom文檔樹的一部分。
在所有的dom節點中attributes屬性是element類型所獨有的的屬性。從技術角度來說,特性就是存在于元素的attributes屬性中的節點。attributes屬性屬于namednodemap類型的執行個體。元素的每一個特性節點都儲存在namednodemap對象中。namednodemap類型擁有如下方法:
getnameditem(name):傳回特性名為name的特性節點
removenameditem(name):删除特性名為name的特性節點
setnameditem(attr):像元素中添加一個特性節點
item(pos):傳回位于數組pos處的節點
擷取、設定、删除元素節點可以如下方式:
實際應用中并不建議使用特性節點的方式,而getattribute、setattribute、removeattribute方法遠比操作特性節點更友善。
dom、attributes、attr三者關系應該這麼畫:
應用總結
基于以上dom基礎知識和實際工作經驗,我将特性和屬性的差別聯系總結如下:
屬性以及公認特性可以通過點文法通路;html5規範中,data-*形式的自定義特性可以通過element.dataset.*的形式來通路,否則用getattribute
特性值隻能是字元串,而屬性值可以是任意javascript支援的類型
幾個特殊特性:
style,通過getattrbute和setattribute來操作這個特性隻能得到或設定字元串;而已屬性方式來操作就是在操作cssstyledeclaration對象
事件處理程式,通過特性方式得到和傳遞的都隻是函數字元串;而已屬性方式操作的是函數對象
value,對于支援value的元素,最好通過屬性方式操作,而且操作不會反映在html标簽上
href,通過屬性方式設定可以反映到html标簽上,但用過點文法和getattribute能夠取到的值并不一定相同
disabled和checked,對于支援這兩個特性的元素來說,他們在html标簽中都是無狀态的,隻要有獨立的标簽屬性在以點文法通路時就傳回true,如果html标簽屬性不存在,則以點文法通路時就是false