摘要:屬性和特性我們知道的實現就是把一個文檔映射為一棵樹,而樹上的每個節點其實就是一個對象。
從jQuery的prop()和attr()方法說開去
jQuery中有兩個獲取DOM元素屬性的方法:prop()和attr(),看似可以互相替換,但若搞不清這兩個方法獲取的到底是什么“屬性”,有時就會出現令人困惑的結果。
官方文檔中,用了下面的例子來解釋這兩者的不同:
操作 | 結果 |
---|---|
elem.checked | true (Boolean) Will change with checkbox state |
$( elem ).prop( "checked" ) | true (Boolean) Will change with checkbox state |
elem.getAttribute( "checked" ) | "checked" (String) Initial state of the checkbox; does not change |
$( elem ).attr( "checked" ) (1.6) | "checked" (String) Initial state of the checkbox; does not change |
$( elem ).attr( "checked" ) (1.6.1+) | "checked" (String) Will change with checkbox state |
$( elem ).attr( "checked" ) (pre-1.6) | true (Boolean) Changed with checkbox state |
我們可以看到,使用prop()當于直接使用了DOM元素對象的屬性,而attr()相當于使用了DOM元素的getAttribute()或setAttribute()方法(而1.6前和1.6后的效果比較特殊,下面會解釋)。這兩種不同的實現,決定了兩種方法獲取到的值并不一樣,這就得涉及到DOM元素屬性(property)和特性(attribute)間的區別了。
屬性(property)和特性(attribute)我們知道DOM的實現就是把一個HTML文檔映射為一棵DOM樹,而DOM樹上的每個節點其實就是一個javascript對象。所以DOM元素屬性和普通對象的屬性一樣,就是DOM對象這個javascript對象上的屬性而已,我們可以直接在DOM對象上通過.或[]來獲取和設置它們,比如:
var formItem = document.querySelector("[name=from-item]"); console.log(formItem.value); /* value0 */ formItem.value = "value1"; /* 文本框顯示“value1”,但此時HTML中的value特性仍為"value0" */ console.log(formItem.value); /* value1 */
而同時在DOM元素節點之外,還有其他類型的節點,比如文本節點、注釋節點、還有我們要討論的特性節點(Attr節點)等等;這些節點當然也是DOM樹上的一個js對象。要操作特性節點,可以在DOM元素上通過getAttribute()、setAttribute()、removeAttribute()等方法來實現,或者用attributes屬性獲取特性節點集合再作操作:
console.log(formItem.getAttribute("value")); /* value0,不受上面屬性設置的影響,仍保持頁面加載后html中的值 */ formItem.setAttribute("value", "value2"); /* 文本框仍顯示“value1”,但此時HTML中的value特性已被改為"value2" */ console.log(formItem.getAttribute("value")); /* value2 */ console.log(formItem.value); /* value1,不隨特性節點的改變而改變 */
上面的例子中,尤其要區分兩點:
屬性和特性兩者不是一一對應的:Attr節點對應的就是HTML各標簽中的特性,這些特性有的未必會被內置為DOM元素的屬性,比如HTML5的data-*特性等自定義特性;而DOM元素的屬性也未必都是HTML中的特性,比如一些DOM元素的操作方法
即使特性節點名和DOM元素的屬性名一致,這兩者的操作和行為也是不同的:
DOM元素的屬性是DOM對象原生實現的,符合一般對象屬性的行為;這些屬性操作和同名的HTML特性節點無關,但可以在顯示上覆蓋HTML特性節點的設置
對于特性節點的操作都是針對HTML文檔上的特性;對特性的操作不會改變同名屬性值,只是改變HTML的文檔內容而已
所以我們可以得到屬性和特性的根本區別了:
DOM元素的屬性(property)是該對象所擁有的屬性,而特性(attribute)則是該元素在HTML中的所擁有的特性節點。property是對象屬性,本身不操作特性節點,但可以覆蓋HTML中的同名特性的效果,是js操作;attribute是DOM節點對象,只用于獲取和設置HTML特性,是文本操作。
用處通過上面的討論,既然屬性和特性有根本性區別,那也就意味著他們的應用場合不太一樣、也不能混淆:
property的操作是純js操作,用于獲取和設置原生的一些特性;并且對于事件屬性如onclick可以獲得處理函數、對于style屬性可以獲得一個對象。
attribute的操作是文本操作,用于獲取和設置HTML文檔中的特性內容,注意這些內容都是字符串形式;同時它能操作的特性也不只是原生限定的那幾種,對于一些拓展特性如data-*也可以操作。
回到一開始舉的jQuery的例子,elem.checked由于是屬性操作,所以可以返回一個布爾值。而elem.getAttribute( "checked" )由于是針對HTML特性的文本操作,所以返回的就是一個字符串,當然這個字符串的值也未必是"checked",而是由HTML中指定的值決定的。
至于為什么attr方法會在jQuery 1.6之前的版本、1.6本身和1.6之后出現各種不一致的行為呢?首先prop方法是在1.6版本之后引入的,之前只有attr時,該方法對返回屬性是還是特性沒有作嚴格區分;而在1.6版本開始會明確讓attr返回特性、prop負責處理屬性,同時1.6后為考慮向后兼容,attr返回特性會隨屬性的改變而改變,但返回的已經只能是“特性形式”的字符串了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/50056.html
摘要:屬性和特性我們知道的實現就是把一個文檔映射為一棵樹,而樹上的每個節點其實就是一個對象。 從jQuery的prop()和attr()方法說開去 jQuery中有兩個獲取DOM元素屬性的方法:prop()和attr(),看似可以互相替換,但若搞不清這兩個方法獲取的到底是什么屬性,有時就會出現令人困惑的結果。官方文檔中,用了下面的例子來解釋這兩者的不同: 操作 結果 elem.c...
摘要:在大多數的文章中,一般被翻譯為特性,被譯為屬性。但是,和并不總是一對一的關系。當修改特性時,屬性也會更新但是修改屬性后,特性卻還是原值。修改特性屬性也更新了修改屬性特性沒有更新非標準特性非標準特性并不會自動映射為屬性。 在大多數的文章中,attribute 一般被翻譯為特性,property 被譯為屬性。 結論 把結論寫在最前面,如果你全都懂,后面就不用看了。 HTML attri...
摘要:在大多數的文章中,一般被翻譯為特性,被譯為屬性。但是,和并不總是一對一的關系。當修改特性時,屬性也會更新但是修改屬性后,特性卻還是原值。修改特性屬性也更新了修改屬性特性沒有更新非標準特性非標準特性并不會自動映射為屬性。 在大多數的文章中,attribute 一般被翻譯為特性,property 被譯為屬性。 結論 把結論寫在最前面,如果你全都懂,后面就不用看了。 HTML attri...
閱讀 1203·2021-11-17 09:33
閱讀 3599·2021-09-28 09:42
閱讀 3326·2021-09-13 10:35
閱讀 2478·2021-09-06 15:00
閱讀 2438·2021-08-27 13:12
閱讀 3609·2021-07-26 23:38
閱讀 1828·2019-08-30 15:55
閱讀 539·2019-08-30 15:53