prop()
和attr()
方法说开去jQuery中有两个获取DOM元素属性的方法:prop()
和attr()
,看似能够互相替换,但若搞不清这两个方法获取的究竟是什么“属性”,有时就会出现使人困惑的结果。
官方文档中,用了下面的例子来解释这二者的不一样:javascript
<input type="checkbox" checked="checked" />
操做 | 结果 |
---|---|
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)间的区别了。html
咱们知道DOM的实现就是把一个HTML文档映射为一棵DOM树,而DOM树上的每一个节点其实就是一个javascript对象。因此DOM元素属性和普通对象的属性同样,就是DOM对象这个javascript对象上的属性而已,咱们能够直接在DOM对象上经过.
或[]
来获取和设置它们,好比:java
<form> <input type="text" name="form-item" value="value0"> </form>
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,不随特性节点的改变而改变 */
上面的例子中,尤为要区分两点:code
属性和特性二者不是一一对应的:Attr节点对应的就是HTML各标签中的特性,这些特性有的未必会被内置为DOM元素的属性,好比HTML5的data-*
特性等自定义特性;而DOM元素的属性也未必都是HTML中的特性,好比一些DOM元素的操做方法orm
即便特性节点名和DOM元素的属性名一致,这二者的操做和行为也是不一样的:htm
DOM元素的属性是DOM对象原生实现的,符合通常对象属性的行为;这些属性操做和同名的HTML特性节点无关,但能够在显示上覆盖HTML特性节点的设置对象
对于特性节点的操做都是针对HTML文档上的特性;对特性的操做不会改变同名属性值,只是改变HTML的文档内容而已事件
因此咱们能够获得属性和特性的根本区别了:ip
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
返回特性会随属性的改变而改变,但返回的已经只能是“特性形式”的字符串了。