深入理解JS中attribute和property的區(qū)別
property 和 attribute非常容易混淆,兩個單詞的中文翻譯也都非常相近(property:屬性,attribute:特性),但實(shí)際上,二者是不同的東西,屬于不同的范疇。
- property是DOM中的屬性,是JavaScript里的對象;
- attribute是HTML標(biāo)簽上的特性,它的值只能夠是字符串;
attribute和property介紹
簡單理解,Attribute就是dom節(jié)點(diǎn)自帶的屬性,例如html中常用的id、class、title、align等。
而Property是這個DOM元素作為對象,其附加的內(nèi)容,例如childNodes、firstChild等。
有以下代碼:
<div id="div1" class="divClass" title="divTitle" title1="divTitle1"></div> var in1=document.getElementById("div1"); console.log(in1);
對于id為div1的div,它的property內(nèi)容如下:(部分)
可以發(fā)現(xiàn)有一個名為“attributes”的屬性,類型是NamedNodeMap,同時有“id”和“className”、”title“等基本的屬性,但沒有“titles”這個自定義的屬性。
console.log(in1.id); //div1 console.log(in1.className); //divClass console.log(in1.title); //divTitle console.log(in1.title1); //undefined
可以發(fā)現(xiàn),標(biāo)簽中的屬性,“id”和“className”、”title“會在in1上創(chuàng)建,而“titles”不會被創(chuàng)建。這是由于,每一個DOM對象都會有它默認(rèn)的基本屬性,而在創(chuàng)建的時候,它只會創(chuàng)建這些基本屬性,我們在TAG標(biāo)簽中自定義的屬性是不會直接放到DOM中的。
那自定義的”title1“去哪里了呢?在attributes屬性里可以看到如下:
“title1”被放在了attributes這個對象里,這個對象按順序記錄了我們在TAG中定義的屬性和屬性的數(shù)量。
從這里就可以看出,attributes是屬于property的一個子集,它保存了HTML標(biāo)簽上定義屬性。如果再進(jìn)一步探索attitudes中的每一個屬性,會發(fā)現(xiàn)它們并不是簡單的對象,它是一個Attr類型的對象,擁有NodeType、NodeName等屬性。關(guān)于這一點(diǎn),稍后再研究。注意,打印attribute屬性不會直接得到對象的值,而是獲取一個包含屬性名和值的字符串,如:
console.log(in1.attibutes.title1); // divTitle1
由此可以得出:
- HTML標(biāo)簽中定義的屬性和值會保存該DOM對象的attributes屬性里面;
- 這些attribute屬性的JavaScript中的類型是Attr,而不僅僅是保存屬性名和值這么簡單;
再如下:
<input id="in_2">
在它的property中有如下部分:
盡管我們沒有在TAG中定義“value”,但由于它是DOM默認(rèn)的基本屬性,在DOM初始化的時候它照樣會被創(chuàng)建。
“腳踏兩只船”
常用的Attribute,例如id、class、title等,已經(jīng)被作為Property附加到DOM對象上,可以和Property一樣取值和賦值。但是自定義的Attribute,就不會有這樣的特殊優(yōu)待,例如:
<div id="div1" class="divClass" title="divTitle" title1="divTitle1">100</div>
這個div里面的“title1”就不會變成Property。
即,只要是DOM標(biāo)簽中出現(xiàn)的屬性(html代碼),都是Attribute。然后有些常用特性(id、class、title等),會被轉(zhuǎn)化為Property??梢院苄蜗蟮恼f,這些特性/屬性,是“腳踏兩只船”的。
最后注意:“class”變成Property之后叫做“className”,因?yàn)?ldquo;class”是ECMA的關(guān)鍵字。
- DOM有其默認(rèn)的基本屬性,而這些屬性就是所謂的“property”,無論如何,它們都會在初始化的時候再DOM對象上創(chuàng)建。
- 如果在TAG對這些屬性進(jìn)行賦值,那么這些值就會作為初始值賦給DOM的同名property。
attribute和property的取值和賦值
1、attribute取值
《js高級程序設(shè)計(jì)》中提到,為了方便操作,建議大家用setAttribute()和getAttribute()來操作即可。
<div id="div1" class="divClass" title="divTitle" align="left" title1="divTitle1"></div> var id = div1.getAttribute("id"); var className1 = div1.getAttribute("class"); var title = div1.getAttribute("title"); var title1 = div1.getAttribute("title1"); //自定義特性
getAttribute()可以取得任何特性,不管是標(biāo)準(zhǔn)的還是自定義的。
但是這個方法的瀏覽器兼容性有問題,有些瀏覽器可能會獲取屬性Property的值,因此jQuery要做一個測試,看getAttribute()是否是絕對獲取特性Attribute的值。
div1.className = 'a'; var judge = div1.getAttribute("className") === 'a';
如果以上代碼成立,說明getAttribute()方法出現(xiàn)了問題,將不再使用。
2、attribute賦值
div1.setAttribute('class', 'a'); div1.setAttribute('title', 'b'); div1.setAttribute('title1', 'c'); div1.setAttribute('title2', 'd');
用setAttrbute()賦值,任何Attribute都可以,包括自定義的。而且,賦值的Attribute會立刻表現(xiàn)到DOM元素上。
如果是標(biāo)準(zhǔn)特性,也會更新它們關(guān)聯(lián)的屬性的值:
最后注意,setAttribute()的兩個參數(shù),都必須是字符串。即對特性Attribute職能賦值字符串,而對屬性Property就可以賦任何類型的值了。
3、property取值
屬性取值很簡單。取任何屬性的只,用“.”就可以:
var id = div1.id; var className = div1.className; var childNodes = div1.childNodes; var attrs = div1.attributes;
此處再次強(qiáng)調(diào):
- class特性在變成屬性時,名字改成了“className”,因此div1.className和div1.getAttrbute('class')相同。
- 上面代碼中的div1.attributes是取的attributes這一屬性,取出來保存到attrs變量中,attrs就成了一個NamedNodeList類型的對象,里面存儲了若干個Attr類型。
4. Property賦值
賦值和基本的js對象屬性賦值一樣,用“.”即可:
div1.className = 'a'; div1.align = 'center'; div1.AAAAA = true; div1.BBBBB = [1, 2, 3];
對屬性Property可以賦任何類型的值,而對特性Attribute只能賦值字符串!
另外,對于屬性Property的賦值在IE中可能會引起循環(huán)引用,內(nèi)存泄漏。為了防止這個問題,jQuery.data()做了特殊處理,解耦了數(shù)據(jù)和DOM對象。
更改property和attribute其中一個值,會出現(xiàn)什么結(jié)果
in1.value='new value of prop'; console.log(in1.value); // 'new value of prop' console.log(in1.attributes.value); // 'value="1"'
此時,頁面中的輸入欄的值變成了“new value of prop”,而propety中的value也變成了新的值,但attributes卻仍然是“1”。從這里可以推斷,property和attribute的同名屬性的值并不是雙向綁定的。
如果反過來,設(shè)置attitudes中的值,效果會怎樣呢?
in2.setAttribute('value','ni') console.log(in2.value); //ni console.log(in2.attributes.value); //value='ni'
由此,可得出結(jié)論:
- property能夠從attribute中得到同步;
- attribute不會同步property上的值;
- attribute和property之間的數(shù)據(jù)綁定是單向的,attribute->property;
- 更改property和attribute上的任意值,都會將更新反映到HTML頁面中;
到此這篇關(guān)于深入理解JS中attribute和property的區(qū)別 的文章就介紹到這了,更多相關(guān)JS attribute property內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一個JS函數(shù)搞定網(wǎng)頁標(biāo)題(title)閃動效果
這篇文章主要介紹了使用JS函數(shù)實(shí)現(xiàn)網(wǎng)頁標(biāo)題(title)閃動效果的代碼,需要的朋友可以參考下2014-05-05javascript實(shí)現(xiàn)點(diǎn)擊按鈕讓DIV層彈性移動的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)點(diǎn)擊按鈕讓DIV層彈性移動的方法,實(shí)例分析了javascript操作div層的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02JS DOMReady事件的六種實(shí)現(xiàn)方法總結(jié)
下面小編就為大家?guī)硪黄狫S DOMReady事件的六種實(shí)現(xiàn)方法總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11java實(shí)現(xiàn)單鏈表增刪改查的實(shí)例代碼詳解
在本篇文章里小編給大家整理了關(guān)于java實(shí)現(xiàn)單鏈表增刪改查的實(shí)例內(nèi)容,需要的朋友們可以參考下。2019-08-08