attribute和property是常常被弄混的兩個概念。
簡單來說,property則是JS代碼里訪問的:
document.getElementByTagName('my-element').prop1 = 'hello';
attribute類似這種:
JS代碼里訪問attribute的方式是getAttribute和setAttribute:
document.getElementByTagName('my-element').setAttribute('attr1','Hello');
document.getElementByTagName('my-element').getAttribute('attr1','Hello');
二、區別
多數情況下,兩者是等效的。在web標準中,常常會規定某attribute“反射”了同名的property。但是例外的情況還是不少的。
1. 名字不一致
最典型的是className,為了回避JavaScript保留字,JS中跟class attribute對應的property是className。
var div = document.getElementByTagName('div');
div.className //cls1 cls2
2. 類型不一致
最典型的是style,不接受字符串型賦值。
var div = document.getElementByTagName('div');
div.style // 對象
3. 語義不一致
如a元素的href屬性。
var a = document.getElementByTagName('a');
a.href // “http://m.taobao.com”,這個url是resolve過的結果
a.getAttribute('href') // “//m.taobao.com”,跟HTML代碼中完全一致
4. 單向同步關系
value是一個極為特殊的attribute/property。
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
除此之外,checkbox的顯示狀態由checked和indeterminate兩個property決定,而只有一個名為checked的property,這種情況下property是更完善的訪問模型。
三、特殊場景
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
});
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com