區分元素特性attribute和對象屬性property
其實attribute和property兩個單詞,翻譯出來都是屬性,但是《javascript高級程序設計》將它們翻譯為特性和屬性,以示區分。本文將詳細介紹特性和屬性的不同之處
定義
元素特性attribute是指HTML元素標簽的特性
下面的id、class、title、a都是特性,其中a叫做自定義特性
<div id="id1" class="class1" title="title1" a=‘a1‘></div>
對象屬性property是指元素節點的屬性
下面的id、title、b都是屬性,其中b叫做自定義屬性
<div id="test"></div><script>test.id = ‘id2‘; test.title = ‘title2‘; test.b = ‘b2‘;</script>
共有
id、title等既是屬性,也是特性。修改屬性,其對應的特性會發生改變;修改特性,屬性也會改變
【1】修改元素特性(以title為例)
<div id="test" title=‘123‘>測試內容</div><script>console.log(test.title);//123document.onclick = function(){ test.setAttribute(‘title‘,‘456‘); console.log(test.title);//456 }</script>
【2】修改對象屬性
<div id="test" title=‘123‘>測試內容</div><script>console.log(test.getAttribute(‘title‘));//123document.onclick = function(){ test.title = ‘456‘; console.log(test.getAttribute(‘title‘));//456 }</script>
例外
class和for這兩個元素特性是例外,因為class和for是保留字,無法直接在對象屬性中使用。所以在對象屬性中,class變成了className,而for變成了htmlFor
【1】class
<div id="test" class="class1">測試內容</div><script>console.log(test.getAttribute(‘class‘));//‘class1‘console.log(test.className);//‘class1‘console.log(test.class);//undefined</script>
【2】for
<label id="test" for="input"></label><script>console.log(test.getAttribute(‘for‘));//‘input‘console.log(test.htmlFor);//‘input‘console.log(test.for);//undefined</script>
特殊
style和onclick是兩個特殊的特性,它們雖然有對應的屬性名,但屬性值與通過getAttribute()返回的值並不相同
【1】style
通過getAttribute()訪問時,返回的style特性值中包含的是CSS文本,而通過屬性來訪問它則會返回一個CSSStyleDeclaration對象
<div id="test" style="height: 100px;width: 100px;"></div><script>console.log(test.getAttribute(‘style‘));//‘height: 100px;width: 100px;‘//{0: "height", 1: "width", alignContent: "", alignItems: "", alignSelf: ""…}console.log(test.style); console.log(typeof test.style);//‘object‘console.log(test.style.height);//‘100px‘</script>
【2】onclick
如果通過getAttribute()訪問,會返回相應代碼的字符串。而訪問onclick屬性時,會返回一個javascript函數
[註意]其他事件處理程序也類似
<div id="test" onclick = "alert(1)">測試內容</div><script> console.log(test.getAttribute(‘onclick‘));//‘alert(1)‘console.log(test.onclick);//‘function onclick(event) {alert(1)}‘console.log(typeof test.onclick);//‘function‘</script>
[註意]如果通過對象屬性設置onclick屬性,則不會有對應的元素特性
<div id="test">測試內容</div><script>test.onclick = function(){ alert(1); } console.log(test.getAttribute(‘onclick‘));//nullconsole.log(test.onclick);//‘function onclick(event) {alert(1)}‘console.log(typeof test.onclick);//‘function‘</script>
自定義
【1】自定義特性
自定義特性用來在HTML元素上綁定一些額外的信息。但是自定義特性無法在對象屬性中有所體現
<div id="test" index=‘1‘></div><script>console.log(test.getAttribute(‘index‘));//‘1‘console.log(test.index);//undefined </script>
HTML5新增了數據集屬性dataset(規範的自定義特性),用於存儲頁面或應用程序的私有定制數據。數據集屬性以‘data-‘為前綴,可以使用javascript中對象屬性dataset訪問data-*的值
由於元素特性的值以‘-‘做間隔,在對象屬性中將轉換為首字母大寫的形式
data-index-one -> dataset.indexOne
所以,元素特性的值一定不要出現大寫,否則對象屬性會解釋出錯
[註意]IE10-瀏覽器不支持dataset
<div id="test" data-index-one="1"></div><script>console.log(test.getAttribute(‘data-index-one‘));//‘1‘console.log(test[‘data-index-one‘]);//undefinedconsole.log(test.dataset.indexOne);//‘1‘</script>
【兼容代碼】
function getDataSet(element){ if(element.dataset){ return element.dataset; } var attrs= element.attributes; var len = attrs.length; var data = {}; for(var i=0;i<len;i++){ var sName = attrs[i].name; var sValue = attrs[i].value; if(sName.substring(0,5)==="data-"){ var tempName = sName.slice(5).replace(/-([A-Za-z])/g,function(item,item1){ return item1.toUpperCase(); }); data[tempName] = sValue; } } return data; }var dataset = getDataSet(box);
【2】自定義屬性
自定義屬性在javascript中非常常用,是一種常用的編程技術。但元素特性上並不會有所體現
<div id="test"></div><script>test.index = 1; console.log(test.index);//1console.log(test.getAttribute(‘index‘));//null</script>
[註意]可以使用數據集屬性的逆向操作來實現自定義屬性向元素特性的對應
<div id="test"></div><script>test.dataset.index = 1; console.log(test.getAttribute(‘data-index‘));//1</script>
混淆
IE7-瀏覽器下會混淆元素特性attribute和對象屬性property。在下列情況下,IE7-瀏覽器通過getAttribute()返回的值與對象屬性相同
【1】class
設置對象屬性className,在IE7-瀏覽器下,訪問元素特性時,參數也設置為className才有效
[註意]for也有類似效果,不再贅述
<div id="test"></div><script>test.className = ‘class1‘;//IE7-瀏覽器返回‘class1‘,其他瀏覽器返回nullconsole.log(test.getAttribute(‘className‘));//IE7-瀏覽器返回null,其他瀏覽器返回‘class1‘console.log(test.getAttribute(‘class‘));</script>
【2】style
IE7-瀏覽器通過getAttribute()方法返回的元素特性與對象屬性一樣,都是CSSStyleDeclaration對象
[註意]click等事件處理程序也有類似效果,不再贅述
<div id="test" style="width: 100px;"></div><script>//IE7-瀏覽器下,返回CSSStyleDeclaration對象;其他瀏覽器返回‘width: 100px;‘console.log(test.getAttribute(‘style‘));//IE7-瀏覽器下,返回true;其他瀏覽器返回falseconsole.log(test.getAttribute(‘style‘) === test.style);</script>
【3】自定義
在IE8-瀏覽器下,自定義特性會自動對應為對象屬性,自定義屬性也會自動對應為元素特性
<div id="test" a=‘a1‘></div><script>test.b = ‘b1‘;//IE7-瀏覽器返回‘a1‘,其他瀏覽器返回undefinedconsole.log(test.a);//IE7-瀏覽器返回‘b1‘,其他瀏覽器返回nullconsole.log(test.getAttribute(‘b‘));</script>
總結
對象節點對於HTML標簽元素說來,是元素DOM化的結果。與此相對應,對象屬性也是元素特性的DOM化結果
由於javascript中保留字的限制,存在class和for這兩種例外情況
與普通的元素特性不同,通過style實現的腳本化CSS機制和通過onclick等實現的事件處理機制是DOM的兩大功能,它們被DOM實現為對象,而不僅僅是普通的字符串
自定義特性和自定義屬性非常有用,但卻沒有對應關系。HTML5新增的數據集屬性dataset建立了兩者的聯系
最後,IE7-瀏覽器對元素特性和對象屬性有所混淆。如果網站仍然需要兼容IE7-瀏覽器,就要非常小心
區分元素特性attribute和對象屬性property