jQuery源码-jQuery.fn.attr与jQuery.fn.prop

jQuery.fn.attr、jQuery.fn.prop的区别

假设页面有下面这么个标签,$('#ddd').attr('nick')、$('#ddd').prop('nick')分别会取得什么值?

<div id="test" nick="casper" class="dddd"></div>

没什么关子好卖,答案如下:

$('#test').attr('nick');  // "casper"
$('#test').prop('nick');  // undefined

再看看下面这几行代码:

$('#test')[0].nick = 'chyingp';
$('#test').attr('age');  // "casper"
$('#test').prop('nick');  // "chyingp"

看到这里应该知道这两个方法的区别了。其实从方法名也可以大致猜出来,.attr()、.prop()分别取的是节点的attribute值、property值。

至于attribute、property的区别,还真不知道怎么解释,有分别翻译成“特性”、“属性”的,这两个词看完后还是有头雾水。我就干脆直接理解成:

attribute: 直接写在标签上的属性,可以通过setAttribute、getAttribute进行设置、读取

property: 通过“.”号来进行设置、读取的属性,就跟Javascript里普通对象属性的读取差不多。

怎么方便怎么记吧。为方便区分,下文统一用特性来代指attribute,用属性来表示property。

 

费解的attribute和property——隐形创建的property

 attribute、property令人费解的地方在于:

1、一些常用attribute,比如id、class、value等,在设置attribute值的时候(直接写标签里,或通过setAttribute方法),会创建对应的property,部分情况下是同名的,比如id

document.getElementsByTagName('div')[0].id;  // "casper"
document.getElementsByTagName('div')[0].getAttribute('id');  // "casper"

2、如1提到的,对某个attribute,创建了对应的property,但却用了不同的名称,比如class,对应的property为className

document.getElementsByTagName('div')[0].className;  // "dddd"
document.getElementsByTagName('div')[0]['class'];  // undefined

所以导致下面代码的诡异之处:

$('test').attr('class', 'dddd');  //有效
$('test').attr('className', 'dddd');  //无效

$('test').prop('class', 'dddd');  //无效
$('test').prop('className', 'dddd');  //有效

 

费解的attribute和property——以checkbox为例

假设页面有这么个复选框,假设它的初始状态为选中

<input type="checkbox" id="box" checked="checked" />

不知道有多少人曾经想我一样,被下面的代码弄得有些抓狂:false、null、"" 轮番上阵,复选框依旧保持“选中”状态

$('#box')[0].setAttribute('checked', false);
$('#box')[0].getAttribute('checked', false);  // 'false'

再试试下面这行代码估计更要抓狂了,T-T

$('#box')[0].checked;  // true

 好吧,如checkbox的checked属性,它的值为Boolean类型,特点是:

1)只要特性checked在标签里出现了,不管值是什么,复选框就会被选中。此时属性checked为true,否则为false;

2)后续修改特性checked的值,不会导致checkbox的选中状态改变;

3)后续修改属性checked的值,会导致checkbox的选中状态改变;

简单demo如下:

<input type="checkbox" id="box" checked="checked" />

<script>
document.getElementById('box').setAttribute('checked', false);
document.getElementById('box').getAttribute('checked');  // "false"
document.getElementById('box').checked;  // true

document.getElementById('box').checked = false;  // 复选框选中态消失

</script>

也可以参考jQuery官网的demo:http://api.jquery.com/attr/

 

.attr()、.prop()源码

.attr()内部是通过jQuery.attr()实现的,.prop()实现类似,所以这里只简单讲一下jQuery.attr()的实现,如下:

其中,大部分的特性值可通过getAttribute、setAttribute进行获取/设置,部分特殊的,比如href、src、checked等,需要调用相应的hook(钩子,很奇怪的名字)的get、set方法几i女性获取/设置值。

可以参照 http://api.jquery.com/attr/ 对.attr() 这个API的讲解,并结合断点调试来理解下面的源码。体力活,不赘述~~

attr: function( elem, name, value ) {
        // 这里一坨代码可以先直接忽视,不影响下面主要逻辑,...代表被忽略的代码
        // ...

        // All attributes are lowercase
        // Grab necessary hook if one is defined
        if ( notxml ) {
            name = name.toLowerCase();
            // 这里几种情况:
            // 1、一些特殊的特性,如href、width等=>attrHooks
            // 2、一些值为Boolean的属性,如checked等=>boolHook
            // 3、其他:nodeHook,主要是针对IE6/7的bug
            hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
        }

        if ( value !== undefined ) {    //设置节点特性,包括:
                                        //$(node).attr('nick','casper')
                                        //或 $(node).attr({'nick':'casper', 'age':100})
                                        //或 $(node).attr('nick', null)

            if ( value === null ) {    // 删除
                jQuery.removeAttr( elem, name );

            } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
                return ret;    // 一些特殊的特性,比如href、src等,有专门的set方法

            } else {    // 普通的setAttribute
                elem.setAttribute( name, value + "" );
                return value;
            }

        } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
            // 获取特性值,且该特性有对应的hook~
            return ret;

        } else {    // 普通的获取特性值

            // In IE9+, Flash objects don't have .getAttribute (#12945)
            // Support: IE9+
            if ( typeof elem.getAttribute !== core_strundefined ) {
                ret =  elem.getAttribute( name );
            }

            // Non-existent attributes return null, we normalize to undefined
            return ret == null ?
                undefined :
                ret;
        }
    }
时间: 2024-09-20 04:29:21

jQuery源码-jQuery.fn.attr与jQuery.fn.prop的相关文章

jQuery源码-美元背后的一点小技巧

写在前面:本文比较基础,仅是一枚菜鸟接触jquery过程中的一点思考和总结,内容较基础,希望能对刚接触jQuery的童鞋有一点帮助 :)    按照国际惯例(其实就是俺写作的习惯),首先抛出待问题的场景.至于问题的答案,文章并不会急着揭晓,而是通过逐层递进的方式,展现思考.解决一个问题的过程   1.如何给一个id为casper的标签添加一个名为"world"的class 考虑下面一个场景,假设我们页面上有个id为casper的div标签,如下所示 <div id="c

Jquery源码分析---概述

jQuery是一个非常优秀的JS库,与Prototype,YUI,Mootools等众多的Js类库 相比,它剑走偏锋,从web开发实用的角度出发,抛除了其它Lib中一些不实用的 东西,为开发者提供了短小精悍的类库.其短小精悍,使用简单方便,性能高效 ,能极大地提高开发效率,是开发web应用的最佳的辅助工具之一.因此大部分 开发者在抛弃Prototype而选择Jquery来进行web开发. 一些开发人员在使用jquery时,由于仅仅只知道Jquery文档中的使用方法, 不明白Jquery的运行原理

Jquery源码分析---导言

jQuery是一个非常优秀的JS库,与Prototype,YUI,Mootools等众多的Js类库 相比,它剑走偏锋,从web开发的实用角度出发,抛除了其它Lib中一些中看但不 实用的东西,为开发者提供了优美短小而精悍的类库.其使用简单,文档丰富, 而且性能高效,能极大地提高web系统的开发效率.因此可以说是web应用开发中 最佳的Js辅助类库之一.大部分开发者正在抛弃Prototype,而选择Jquery做为 他们进行web开发的JS库. 如是开发人员仅仅只知道文档中的简单的使用 方法,却不明

jQuery源码-dom操作之jQuery.fn.html

写在前面 前面陆陆续续写了jQuery源码的一些分析,尽可能地想要cover里面的源码细节,结果导致进度有些缓慢.jQuery的源码本来就比较晦涩,里面还有很多为了解决兼容问题很引入的神代码,如果不google的话压根不知道那一段段代码为什么会存在于人世. 于是就一直在重复坐着这么件事情,到处谷歌或者请教别人,这段兼容代码是为解决神马问题引入的.好不容易把所有的源码细节搞清楚,喝着咖啡对着电脑欣赏自己的劳动成果,内心却闪过一丝奇怪的感觉:我花了这么长的时间究竟做了什么?就为了搞清楚这段常理无法解

jQuery源码分析之jQuery.fn.each与jQuery.each用法_jquery

本文实例讲述了jQuery源码分析之jQuery.fn.each与jQuery.each用法.分享给大家供大家参考.具体分析如下: 先上例子,下面代码的作用是:对每个选中的div元素,都给它们添加一个red类 复制代码 代码如下: $('div').each(function(index, elem){       $(this).addClass('red'); } }); 上面用的的.each,即jQuery.fn.each,其内部是通过jQuery.each实现的 复制代码 代码如下: j

jQuery源码解读之removeAttr()方法分析

 这篇文章主要介绍了jQuery源码解读之removeAttr()方法分析,较为详细的分析了removeAttr方法的实现技巧,非常具有实用价值,需要的朋友可以参考下     本文较为详细的分析了jQuery源码解读之removeAttr()方法.分享给大家供大家参考.具体分析如下: 扩展jQuery原型对象的方法: 代码如下: jQuery.fn.extend({ //name,传入要DOM元素要移除的属性名. removeAttr: function( name ) {   //使用jQue

jQuery源码-jQuery.extend

从jQuery的源码中可以看到,jQuery.extend和jQuery.fn.extend其实是同指向同一方法的不同引用 jQuery.extend = jQuery.fn.extend = function() { 瞄了下它的代码,其实不复杂,但是在jQuery中扮演了极其重要的作用 jQuery.extend 对jQuery本身的属性和方法进行了扩展 jQuery.fn.extend 对jQuery.fn的属性和方法进行了扩展 // 扩展jQuery对象本身,此处添加了jQuery.noC

jQuery源码-CSS样式相关部分

jquery版本:1.7.2 根据实际需要,对CSS部分无关代码进行适当删除,如有疑问,可参见jquery源码:http://code.jquery.com/jquery-1.7.2.js 因实际工作中暂时没有用到jquery,故对jquery了解很粗浅,文章可能有错漏之处,敬请见谅并指出 本文参考借鉴了nuysoft 的jquery源码分析系列,挺不错的系列文章,推荐下: http://www.cnblogs.com/nuysoft/archive/2011/11/14/2248023.htm

jQuery源码分析-03构造jQuery对象-工具函数_jquery

作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. 读读写写,不对的地方请告诉我,多多交流共同进步,本章的的PDF等本章写完了发布. jQuery源码分析系列的目录请查看 http://nuysoft.iteye.com/blog/1177451,想系统的好好写写,目前还是从我感兴趣的部分开始,如果大家有对哪个模块感兴趣的,建议优先分析的,可以告诉我,一起学习. 3.4 其他静态工具函数