jquery1.6版本后引入了prop()方法,很多时候总是混淆attr()与prop()这俩,下面分析一下这俩的区别

在此之前,先来了解一下html 的attribute和property,因为jquery的attr()和prop()正是来源于这俩东西。先看一段html代码:

<span  id="testId" class="testClass" selfAttribute="selfValue"></span>

根据 DOM (HTML) 规范,SPAN 元素在页面中生成一个相对应的对象,对象有一个标识为id的attribute,对于attribute,我们称为HTML标签属性,对于property,为DOM对象属性,注意下面这句话:

HTML 标签的属性会将其值暴露给对应的 DOM 对象的属性,如 HTML 元素的 id 属性与其对应的 DOM 对象的 id 属性会保持一种同步关系

所以该元素的dom对象中也会生成key为id的 property,所以可以通过key直接获得值,看下面的例子

var testId =  document.getElementById("testId");
console.log(testId.id);//testId
console.log(testId.getAttribute("id"));//testId

这样一来是不是以后获取属性值都直接用.访问就可以了,下面继续看:

 var testId =  document.getElementById("testId");
console.log(testId.class);//undefinde
console.log(testId.getAttribute("class"));//testClass

当我们直接访问class时,并没有得到我们期望的testClass,原因是在 HTML 标签中使用 class 属性指定元素使用的 CSS 类,但在 DOM 对象中由于 class 是 ECMAScript 的保留字,所以改用 className 属性,所以想直接获取class值,修改一下即可:

console.log(testId.className);//testClass

上面的例子可以知道 ,对于部分 "property" 与 "attribute" 在名称及值类型上是统一的,对于我们经常用到的自定义属性,可以继续做个测试:

 var testId =  document.getElementById("testId");
console.log(testId.selfAttribute);//undefined
console.log(testId.getAttribute("selfAttribute"));//selfValue

testId.selfAttribute为undefined说明property与attribute并不共享自定义属性,引用别人的一张图来表示一下:

    

对于build-in区域的属性,property和attribute是共享的,比如id,但是IE6、7没有作区分,依然共享自定义属性数据,因为IE 混淆了 DOM 对象属性(property)及 HTML 标签属性(attribute),造成了对 setAttribute、getAttribute 的不正确实现,参考http://www.w3help.org/zh-cn/causes/SD9006

对于自定义的属性两者互不干涉,即使name是相同的,看下面例子:

 var testId =  document.getElementById("testId");
testId.setAttribute("stk1","stv1");
console.log(testId.stk1);//undefined
console.log(testId.getAttribute("stk1"));//selfValue
testId.stk1 = "stv2";
console.log(testId.stk1);//stv2
console.log(testId.getAttribute("stk1"));//stv1

此外,对于值是true/false的property,类似于input的checked attribute等,attribute取得值是HTML文档字面量值,property是取得计算结果,property改变并不影响attribute字面量,但attribute改变会影响property计算

<input type="checkbox" id="checkboxId"/>
var checkbox1 =  document.getElementById("checkboxId");

         alert(checkbox1.checked);//false
alert(checkbox1.getAttribute("checked"));//null /* checkbox1.setAttribute("checked","checked");
alert(checkbox1.checked);//true, setAttribute影响property*/ checkbox1.checked = true;
alert(checkbox1.getAttribute("checked"));//null property不影响setAttribute影响property

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

<a id="testA" href="#">Click</a>
 var testA =  document.getElementById("testA");
console.log(testA.href);//file:///C:/Users/%E6%B0%B8%E4%BF%A1/Desktop/static/main.html#
console.log(testA.getAttribute("href"));//#

看完上面的文章,看一下主题,attr() 和 prop()

首先贴源码:

attr:

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:

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对象
});
  1. el.attr(“style”)输出undefined,因为attr是获取的这个对象属性节点的值,很显然此时没有这个属性节点,自然输出undefined
  2. el.prop(“style”)输出CSSStyleDeclaration对象,对于一个DOM对象,是具有原生的style对象属性的,所以输出了style对象
  3. 至于document.getElementById(“test”).style和上面那条一样
el.attr("abc","111")
console.log(el.attr("abc")); //
console.log(el.prop("abc")); //undefined

首先用attr方法给这个对象添加abc节点属性,值为111,可以看到html的结构也变了

  1. el.attr(“abc”)输出结果为111,再正常不过了
  2. el.prop(“abc”)输出undefined,因为abc是在这个的属性节点中,所以通过prop是取不到的

我们再接着来:

el.prop("abc", "222");
console.log(el.attr("abc")); //
console.log(el.prop("abc")); //

我们再用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

关于checked 属性需要记住的最重要的一点是:它和checked property并不是一致的。实际上这个attribute和defaultChecked property一致,而且只应该用来设置checkbox的初始值。checked attribute并不随着checkedbox的状态而改变,但是checked property却跟着变。因此浏览器兼容的判断checkebox是否被选中应该使用property

对jquery的 attr()和prop()理解的更多相关文章

  1. jQuery中.attr()和.prop()的区别

    之前学习jQuery的时候,学习到了两种取得标签的属性值的方法:一种是elemJobj.attr(),另一种是elemJobj.prop().而在学习JS的时候,只有一种方法elemObj.getAt ...

  2. jQuery中attr和prop方法的区别说明

    jquery中attr和prop的基本区别可以理解为:如果是内置属性,建议用prop,如果是自定义的建议用attr. 例如 <input type=check  node=123 id=ck & ...

  3. jQuery中attr()与prop()区别介绍

    .attr() : 获取匹配的元素集合中的第一个元素的属性的值 或 设置每一个匹配元素的一个或多个属性. •.attr( attributeName ) •.attr( attributeName ) ...

  4. jQuery中attr和prop方法的区别

    jQuery中attr和prop方法的区别。 http://my.oschina.net/bosscheng/blog/125833 http://www.javascript100.com/?p=8 ...

  5. jquery中attr和prop的区别、 什么时候用 attr 什么时候用 prop (转自 芈老头 )

    jquery中attr和prop的区别. 什么时候用 attr 什么时候用 prop   在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这 ...

  6. jquery中attr和prop的区别(转)

    在网络上看到这样一篇关于jquery中attr和prop的区别文章,觉得不错,所以转载了. 在jQuery 1.6中,.attr()方法查询那些没有设置的属性,则会返回一个undefined.如果你要 ...

  7. jquery中attr()与prop()函数用法实例详解(附用法区别)

    本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是a ...

  8. jquery中attr和prop的区别分析

    这篇文章主要介绍了jquery中attr和prop的区别分析的相关资料,需要的朋友可以参考下 在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别 ...

  9. tips:Jquery的attr和prop的区别

    Jquery的attr和prop的区别 描述:想做一个复选框checkbox全选的功能,当勾选全选后,将子项的复选框状态设置成一致的, 但遇到了一个问题,就是attr函数并不能改变子项的checkbo ...

随机推荐

  1. Android学习之散乱的知识点

    1. 安卓广告知名平台:有米,哇棒,架势,admob(国外,但效果不好)等,推荐用有米 2. src目录为源文件目录,所有可以被用户修改和创建的Java文件将被存放在这个目录下 3. xml中引用st ...

  2. 数据结构 -- 简单图的实现与遍历 (Java)

    ---恢复内容开始--- 作者版权所有,转载请注明出处,多谢. http://www.cnblogs.com/Henvealf/p/5534071.html 前些天因为某些原因,就试着回想一下图(gr ...

  3. 原生JS默认设置默认值的写法

    json=json||{};json.type=json.type||'get';json.data=json.data||{};json.time=json.time||2000;

  4. 网上关于sort结构体排序都不完整,我来写一个完整版的 2014-08-09 16:50 60人阅读 评论(0) 收藏

    主要参考sort函数_百度文库, 但是那篇有错误 2.结构体排序,a升,b降,c降 平板视图 打印? 01 #include <iostream> 02 #include <algo ...

  5. Symbol Table

    [Symbol Table] In order for GDB to be useful to us, it needs to be able to refer to variable and fun ...

  6. codeforces 601A The Two Routes(最短路 flody)

    A. The Two Routes time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  7. 一种将Region转为Polyline的方法

    在AutoCAD.NET二次开发中,如果要将面域转为Polyline主要有以下几种方式: 1.使用Explode将面域炸成Line和Arc,然后再串起来,此方法可用于AutoCAD2007开始的所有版 ...

  8. 修改hosts文件解决OneDrive被墙的问题

    增加如下内容就可以了.如果不知道修改hosts文件的具体方法请自行百度. 134.170.108.26 onedrive.live.com 134.170.108.152 skyapi.onedriv ...

  9. HDU 1312 Red and Black DFS(深度优先搜索) 和 BFS(广度优先搜索)

    Red and Black Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

  10. web.xml filter 顺序

    The order the container uses in building the chain of filters to be applied for a particular request ...