.attr()和.prop()和.css()的区别

是不是新手都会遇到这个问题?遇到过一次,在网上搜一搜,综合成了下面这样。重点参考了dolphin的‘jQuery的attr与prop’,谢谢啦,写的很清楚呢。

一般attribute翻译成中文术语为特性property翻译成中文术语为属性.

1.attribute

 attribute可以看作是一个特性节点,每个DOM元素都有一个对应的attributes属性来存放所有的attribute节点,attributes是一个类数组的容器。

如<div id=‘divId‘ customizedV=‘value1‘></div>,对于这个div元素来说,他的attributes里就存了两个attribute节点,类似于这样:[id:‘divId‘,customizedV:‘value1‘]。可以这样来访问attribute节点:obj.attributes[0].id;//divId  obj.attributes[0].customizedV;//value1 。

但是IE6-7将很多东西都存放在attributes中,上面的访问方法和标准浏览器的返回结果又不同,所以通常获取一个attribute特性值用obj.getAttribute(vName)、obj.setAttribute(‘vName‘,‘value‘)、obj.removeAttribute(‘vName‘)。

对于添加的自定义attribute会显示在html文件里(用.attr()取那些已经显示在html里的特性肯定是不会出错的),非自定义的attribute虽然有些并没有显示在html里,本以为会有一个默认值,但是对chrome测试发现,没有显式的设置attribute的值,就无法getgetAttribute。如:

<input id=‘myInputId‘ type="checkbox" >

alert(obj.getAttribute(‘checked‘));//null

alert($(obj).attr(‘checked‘));//undefined

对<img src=‘title.gif‘ >的alt也是如此。

2.property

property是DOM对象的一个字段,跟我们平常使用的对象的字段/属性一样,取值或者设置值和普通字段一样直接通过”对象.字段“的方式。比如添加的自定义property就直接是obj.myOwnProp=‘value2‘;设置的property不会显示在html文件里。你是不是在想:这样不就可以利用property在节点上存储一些自己的信息流么?在IE9之前版本中,如果property没有在DOM元素被移除之前删除,使用.prop()方法设置DOM元素property(简单类型除外:number、string、boolean)的值会导致内存泄露。为了安全的设置DOM对象的值,避免内存泄露,可以使用jQuery专门在元素上存放数据的方法:.data()方法。

对于<input id=‘myInputId‘>,可以在chrome看到列出来这个inputDom对象的字段:

 

3、为什么容易混淆

看似二者并不相关,容易混淆是因为:很多attribute节点还有一个相对应的property属性。意思是指DOM对象的一些property属性和attribute节点是一样的。
如id:obj.getAttribute(id)和obj.id都能取得id的值。
但是并不是所有的attribute与对应的property名字都一致。
如attribute 的class对应property的是className。

3.1、attribute和property共享数据,attribute更改了会对property造成影响,反之亦然。如:

obj.setAttribute(‘class‘,‘class1‘);
obj.className=‘class2‘;
console.log(obj.getAttribute(‘class‘));//class2。
但是两者的自定义属性是独立的数据,即使name一样,也互不影响。如:
obj.setAttribute(‘ customizedV‘,‘value1‘);
  obj.customizedV=’value2’;

console.log(obj.getAttribute(customizedV‘)); //value1。

但是IE6、7没有作区分,自定义属性数据也是共享的。

3.2、对于值是true/false的property,如input:checkbox的checked等,attribute取的值是HTML文档字面量值,property取的计算结果。

在chrome中测试:对于<input id=‘myInputId‘ type="checkbox" checked>

console.log(obj.getAttribute(‘checked‘)+‘:‘+typeof obj.getAttribute(‘checked‘)); //:string

console.log(obj.checked+‘:‘+typeof obj.checked);               //true:boolean

对于checked=‘true‘和checked=true都是// true:string //true:boolean

对checked=1时//1:string //true:Boolean

对checked=0(注意此时checkbox仍然处于选中状态)时//0:string //true:boolean

 对checked=‘false‘和checked= false(注意此时checkbox仍然处于选中状态)时// false:string //true:boolean

3.3、对于值是true/false的property,如input:checkbox的checked等,property的改变并不影响attribute字面量。如:

<input id=‘myInputId‘ type="checkbox" >

obj.setAttribute(‘checked‘,false);

obj.checked=true;

console.log(obj.getAttribute(‘checked‘));//false,注意checkbox处于选中状态。

对于<input id=‘myInputId‘ type="checkbox" checked="true">即使obj.setAttribute(‘checked‘,‘false‘);checkbox也会依然处于选中状态。

但是attribute改变会影响property计算。如:

<input id=‘myInputId‘ type="checkbox" >

obj.checked=false;

obj.setAttribute(‘checked‘, false);//或obj.setAttribute(‘checked‘,’ false’);

alert(obj.checked);//true, checkbox处于选中状态

是不是很奇怪:虽然attribute的确影响了property,但是只要设置了obj.setAttribute(‘checked‘, ‘…’);不过值是多少,都认为是选中状态,以及前面例子里出现的checkbox总是处于选中状态是怎么回事?

在dolphin的‘jQuery的attr与prop’中有说明为什么:

根据W3C forms specification,checked属性是一个布尔值,这就意味着只要checked属性在HTML中表现出来了,那么相应的property就应该是true,即使checked没有值,这点儿对其它布尔类型的属性一样适用。

关于checked需要记住的最重要的一点是:这个特性和checked property并不是一致的。实际上这个attribute和defaultChecked property一致,而且只应该用来设置checkbox的初始值。所以才会导致checked attribute并不随着checkedbox的状态而改变,只有checked property会跟着变。因此浏览器兼容的判断checkebox是否被选中应该使用property。这对其它一些类似于selected这样的动态attribute也适用。

注意下面情况:

对于<input id=‘myInputId‘ type="checkbox"  checked="true">,在chrome中测试:

$(obj).attr(‘checked‘,‘false‘);//注意:处于选中状态

obj.setAttribute(‘checked‘,’ false’);//处于选中状态

$(obj).attr(‘checked‘,false);  //处于没有选中状态

obj.setAttribute(‘checked‘, false);//处于选中状态

$(obj).prop(‘checked‘,‘false‘);//注意:处于选中状态

obj.checked=‘false‘;//注意:处于选中状态 

$(obj).prop(‘checked‘,false);//处于没有选中状态 

obj.checked=false;//处于没有选中状态

可以看到attribute和property都是严格区分‘false‘和false的,另外jQuery对.attr的false做了改变,与原始的setAttribute(‘checked‘, false)不同了。

3.4、对于一些和路径相关的属性,两者取得值也不尽相同,但是同样attribute取得是字面量,property取得是计算后的完整路径。如:

对于<a id="test4" href="#">Click</a>
    var obj=document.getElementById(‘test4‘);
    console.log(obj.getAttribute(‘href‘));//#
    console.log(obj.href);//file:///C:/Users/bsun/Desktop/ss/anonymous.html#

另外在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。

4、.css()与它们的区别自然很明显了,这个方法只能用来获取/设置DOM对象的样式。

如color、background,对应js里的obj.style.样式名=样式值。

 

 

.attr()和.prop()和.css()的区别,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。