jQuery的attr与prop使用介绍
来源:互联网 发布:刘文典打蒋介石知乎 编辑:程序博客网 时间:2024/06/15 00:22
jQuery的attr与prop使用介绍
attribute和property都可以翻译为属性,为了以示区别,通常把这两个单词翻译为属性与特性。
<div id="test">Click Here</div>
上面这段HTML语句中有三个节点,分别是Element “div”、attribute “id”、Text “click here”,我们最常见的attribute正式指的attribute类型节点,在JavaScript有专门处理attribute的函数 .getAttribute(name) / setAttribute(name,value)。当然attribute不只是我们能够在HTML文档上看到的这几个,我们可以自定义attributed加到DOM节点中
<div id="test">123</div>
<script type="text/javascript">
var t=document.getElementById('test');
t.setAttribute('class','active');
t.setAttribute('customizedAttr','customized');
</script>
这样可以div被修改为
通过方法 setAttribute设置的attribute最终都会反映到元素的attribute类型的节点中
property是DOM对象的字段,跟我们平常使用的一些对象一样,包含很多字段,这些字段就是property,取值或者设置值和普通字段一样通过”对象.字段“的方式。
看起来attribute和property应该没有什么关系才对,怎么会。。。attribute和property容易混倄是因为很多attribute节点还有一个相对应的property属性,比如上面div的”id“ attribute 同样可以用t.id取到(实际上绝大部分人都是这样获取的),通过property更改id后,用getAttibute获取的id是更新后的id。
t.id='test1';
console.log(t.getAttribute('id'));//test1
同样我们也可以自定义property
t.customizedProp='customized prop';
区别
1. 于build-in属性,attribute和property共享数据,attribute更改了会对property造成影响,反之亦然,但是两者的自定义属性是独立的数据,即使name一样,也互不影响,看起来是下面这张图,但是IE6、7没有作区分,依然共享自定义属性数据
2. 并不是所有的attribute与对应的property名字都一致,比如刚才使用的attribute 的class属性,使用property操作的时候应该是这样className
3. 对于值是true/false的property,类似于input的checked attribute等,attribute取得值是HTML文档字面量值,property是取得计算结果,property改变并不影响attribute字面量,但attribute改变会一向property计算
var t=document.getElementById('test3');
console.log(t.getAttribute('checked'));//null
console.log(t.checked);//false;
t.setAttribute('checked','checked');
console.log(t.getAttribute('checked'));//checked
console.log(t.checked);//true
t.checked=false;
console.log(t.getAttribute('checked'));//checked
console.log(t.checked);//false
4. 对于一些和路径相关的属性,两者取得值也不尽相同,但是同样attribute取得是字面量,property取得是计算后的完整路径
<a id="test4" href="#">Click</a>
var t=document.getElementById('test4');
console.log(t.getAttribute('href'));//#
console.log(t.href);//file:///C:/Users/bsun/Desktop/ss/anonymous.html#
关于浏览器(IE)造成的兼容性问题可以看看IE 混淆了 DOM 对象属性(property)及 HTML 标签属性(attribute),造成了对 setAttribute、getAttribute 的不正确实现
attr和prop
相信看完上面内容,大家就明白为什么jQuery要添加prop方法了,在jQuery API中也有专门解释
Attributes VS. Properties
在一些特殊的情况下,attributes和properties的区别非常大。在jQuery1.6之前,.attr()方法在获取一些attributes的时候使用了property值,这样会导致一些不一致的行为。在jQuery1.6中,.prop()方法提供了一中明确的获取property值得方式,这样.attr()方法仅返回attributes。
比如,selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, 和defaultSelected应该使用.prop()方法获取/设置值。 在jQuery1.6之前这些不属于attribute的property需要用.attr()方法获取。这几个并没有相应的attibute,只有property。
关于布尔类型 attributes,比如一个这样的HTML标签,它在JavaScript中变量名为elem
<input type="checkbox" checked="checked" />
true
(Boolean) Will change with checkbox state$( elem ).prop( "checked" )true
(Boolean) Will change with checkbox stateelem.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
根据W3C forms specification,checked属性是一个布尔值,这就意味着只要checked属性在HTML中表现出来了,那么相应的property就应该是true,即使checked没有值,这点儿对其它布尔类型的属性一样适用。
然而关于checked 属性需要记住的最重要的一点是:它和checked property并不是一致的。实际上这个attribute和defaultChecked property一致,而且只应该用来设置checkbox的初始值。checked attribute并不随着checkedbox的状态而改变,但是checked property却跟着变。因此浏览器兼容的判断checkebox是否被选中应该使用property
if ( elem.checked )
if ( $( elem ).prop( "checked" ) )
if ( $( elem ).is( ":checked" ) )
这对其它一些类似于selected、value这样的动态attribute也适用。
在IE9之前版本中,如果property没有在DOM元素被移除之前删除,使用.prop()方法设置DOM元素property(简单类型除外:number、string、boolean)的值会导致内存泄露。为了安全的设置DOM对象的值,避免内存泄露,可以使用.data()方法。
使用场景
其实明白了上面讲的内容,什么时候该使用.attr()什么时候该使用 .prop()就很清楚了,不过还是传一张坊间很流行的图
相比attr,prop是1.6.1才新出来的,两者从中文意思理解,都是获取/设置属性的方法(attributes和properties)。只是,window或document中使用.attr()方法在jQuery1.6之前不能正常运行,因为window和document中不能有attributes。prop应运而生了。
既然我们想知道他们两的区别,最好就看看他们的源代码,不要被代码长度所吓到,我们只看关键的几句:
attr: function( elem, name, value, pass ) {
var ret, hooks, notxml,
nType = elem.nodeType;
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
return jQuery( elem )[ name ]( value );
}
// Fallback to prop when attributes are not supported
if ( typeof elem.getAttribute === "undefined" ) {
return jQuery.prop( elem, name, value );
}
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
// All attributes are lowercase
// Grab necessary hook if one is defined
if ( notxml ) {
name = name.toLowerCase();
hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
}
if ( value !== undefined ) {
if ( value === null ) {
jQuery.removeAttr( elem, name );
return;
} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
elem.setAttribute( name, value + "" );
return value;
}
} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
return ret;
} else {
ret = elem.getAttribute( name );
// Non-existent attributes return null, we normalize to undefined
return ret === null ?
undefined :
ret;
}
}
prop方法代码(jQuery版本1.8.3)
prop: function( elem, name, value ) {
var ret, hooks, notxml,
nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
if ( notxml ) {
// Fix name and attach hooks
name = jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ];
}
if ( value !== undefined ) {
if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
return ( elem[ name ] = value );
}
} else {
if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
return ret;
} else {
return elem[ name ];
}
}
}
attr方法里面,最关键的两行代码,elem.setAttribute( name, value + “” )和ret = elem.getAttribute( name ),很明显的看出来,使用的DOM的API setAttribute和getAttribute方法操作的属性元素节点。
而prop方法里面,最关键的两行代码,return ( elem[ name ] = value )和return elem[ name ],你可以理解成这样document.getElementById(el)[name] = value,这是转化成JS对象的一个属性。
既然明白了原理是这样,我们来看看一个例子:
<input type="checkbox" id="test" abc="111" />
$(function(){
el = $("#test");
console.log(el.attr("style")); //undefined
console.log(el.prop("style")); //CSSStyleDeclaration对象
console.log(document.getElementById("test").style); //CSSStyleDeclaration对象
});
el.attr(“style”)输出undefined,因为attr是获取的这个对象属性节点的值,很显然此时没有这个属性节点,自然输出undefined
el.prop(“style”)输出CSSStyleDeclaration对象,对于一个DOM对象,是具有原生的style对象属性的,所以输出了style对象
至于document.getElementById(“test”).style和上面那条一样
接着看:
el.attr("abc","111")
console.log(el.attr("abc")); //111
console.log(el.prop("abc")); //undefined
首先用attr方法给这个对象添加abc节点属性,值为111,可以看到html的结构也变了
el.attr(“abc”)输出结果为111,再正常不过了
el.prop(“abc”)输出undefined,因为abc是在这个的属性节点中,所以通过prop是取不到的
el.prop("abc", "222");
console.log(el.attr("abc")); //111
console.log(el.prop("abc")); //222
我们再用prop方法给这个对象设置了abc属性,值为222,可以看到html的结构是没有变化的。输出的结果就不解释了。
上面已经把原理讲清楚了,什么时候用什么就可以自己把握了。
提一下,在遇到要获取或设置checked,selected,readonly和disabled等属性时,用prop方法显然更好,比如像下面这样:
<input type="checkbox" id="test" checked="checked" />
console.log(el.attr("checked")); //checked
console.log(el.prop("checked")); //true
console.log(el.attr("disabled")); //undefined
console.log(el.prop("disabled")); //false
显然,布尔值比字符串值让接下来的处理更合理。
PS一下,如果你有JS性能洁癖的话,显然prop的性能更高,因为attr需要访问DOM属性节点,访问DOM是最耗时的。这种情况适用于多选项全选和反选的情况。
大家都知道有的浏览器只要写disabled,checked就可以了,而有的要写成disabled = "disabled",checked="checked",比如用attr("checked")获取checkbox的checked属性时选中的时候可以取到值,值为"checked"但没选中获取值就是undefined。
jq提供新的方法“prop”来获取这些属性,就是来解决这个问题的,以前我们使用attr获取checked属性时返回"checked"和"",现在使用prop方法获取属性则统一返回true和false。
那么,什么时候使用attr(),什么时候使用prop()?
1.添加属性名称该属性就会生效应该使用prop();
2.是有true,false两个属性使用prop();
3.其他则使用attr();
项目中jquery升级的时候大家要注意这点!
- jQuery的attr与prop使用介绍
- jQuery的attr与prop使用介绍
- jQuery的attr与prop使用区别
- JQuery_JQuery的attr与prop使用介绍
- jQuery的attr与prop
- jQuery的attr与prop
- jQuery的attr与prop
- jQuery的attr与prop
- jQuery的attr与prop
- jQuery的attr与prop
- jQuery的attr与prop
- jquery的attr() 与prop()
- jquery: prop 与 attr
- 【Jquery】prop与attr的区别
- jquery attr与prop 的区别
- jquery中attr与prop的区别
- jQuery中attr()与prop()的区别
- jquery中attr()与prop()的区别
- 音乐发展史的革命--摇滚,ROCK & ROLL
- sgu102:Coprimes
- 【网络爬虫】【python】网络爬虫(三):模拟登录——伪装浏览器登录爬取过程
- Ubuntu 12.04 install Open vSwitch
- HDU 1166
- jQuery的attr与prop使用介绍
- windowsform中的控件调用--1
- HDU 3455 Leap Frog(线性DP)
- 求两大整数相乘
- sgu104:Little Shop of Flowers
- Android 分享一个流量显示界面
- 图的邻接矩阵存储结构
- windows 10预览版 ISO原版安装镜像文件
- GridLayout向后兼容问题