HTML中的attribute和property

1、概述web

attribute和property是經常被弄混的兩個概念。url

簡單來講,property則是JS代碼裏訪問的:prototype

document.getElementByTagName('my-element').prop1 = 'hello';server

attribute相似這種:對象

<my-element attr1="cool" />ip

JS代碼裏訪問attribute的方式是getAttribute和setAttribute:element

document.getElementByTagName('my-element').setAttribute('attr1','Hello');字符串

document.getElementByTagName('my-element').getAttribute('attr1','Hello');get

2、區別input

多數狀況下,二者是等效的。在web標準中,經常會規定某attribute「反射」了同名的property。可是例外的狀況仍是很多的。

1. 名字不一致

最典型的是className,爲了迴避JavaScript保留字,JS中跟class attribute對應的property是className。

<div class="cls1 cls2"></div>

<script>

var div = document.getElementByTagName('div');

div.className //cls1 cls2

</scrpit>

2. 類型不一致

最典型的是style,不接受字符串型賦值。

<div class="cls1 cls2" style="color:blue" ></div>

<script>

var div = document.getElementByTagName('div');

div.style // 對象

</scrpit>

3. 語義不一致

如a元素的href屬性。

<a href="//m.taobao.com" ></div>

<script>

var a = document.getElementByTagName('a');

a.href // 「http://m.taobao.com」,這個url是resolve過的結果

a.getAttribute('href') // 「//m.taobao.com」,跟HTML代碼中徹底一致

</scrpit>

4. 單向同步關係

value是一個極爲特殊的attribute/property。

<input value = "cute" />

<script>

var input = document.getElementByTagName('input');

//若property沒有設置,則結果是attribute

input.value //cute

input.getAttribute('value'); //cute

 

input.value = 'hello';

//若value屬性已經設置,則attribute不變,property變化,元素上實際的效果是property優先

input.value //hello

input.getAttribute('value'); //cute

</scrpit>

除此以外,checkbox的顯示狀態由checked和indeterminate兩個property決定,而只有一個名爲checked的property,這種狀況下property是更完善的訪問模型。

3、特殊場景

1.mutation

使用mutation observer,只能監測到attribute變化。

var observer = new MutationObserver(function(mutations){

for(var i = 0; i < mutations.length; i++) {

var mutation = mutations[i];

console.log(mutation.attributeName);

}

});

observer.observe(element,{attributes:true});

element.prop1 = 'aa' // 不會觸發

element.setAttribute('attr1', 'aa') //會觸發

2.custom element

在使用WebComponents時,能夠定義attribute和property,二者能夠互相反射,也能夠全無關聯。

var MyElementProto = Object.create(HTMLElement.prototype, {

createdCallback : {

value : function() { }

}

});

 

//定義property

Object.defineProperty(MyElementProto,'prop1', {

get:function(){

return //

},

set:function(){

console.log('property change');//do something

}

});

 

//定義attribute

MyElementProto.attributeChangedCallback = function(attr, oldVal, newVal) {

if(attr === 'attr1') {

console.log('attribute change');//do something

}

};

 

window.MyElement = document.registerElement('my-element', {

prototype: MyElementProto

});

相關文章
相關標籤/搜索