我们知道,$().attr()实质上是内部调用了jQuery.access方法,在调用时jQuery.attr作为回调传入。在通过种种判断(参看jQuery.access()方法)之后,取值和赋值最后调用了这个jQuery.attr方法。

所以,关键是看jQuery.attr这里怎么走了~~

源码如下:

   attr: function( elem, name, value ) {
var hooks, ret,
nType = elem.nodeType;
//如果elem不存在,或者是文本、注释、属性节点
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
} // Fallback to prop when attributes are not supported
if ( typeof elem.getAttribute === core_strundefined ) {//如果elem不支持getAttribute 比如document或者文档碎片
return jQuery.prop( elem, name, value );//调用jQuery.prop方法
} // All attributes are lowercase
// Grab necessary hook if one is defined
//?
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {//elem不是标签或者elem不在xml中
name = name.toLowerCase();//属性名大写
hooks = jQuery.attrHooks[ name ] ||
( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );//jQuery.attrHooks.type
} if ( value !== undefined ) {//赋值 if ( value === null ) {//如果设的值为null,相当于移除attr ,比如.attr('checked',null);
jQuery.removeAttr( elem, name ); } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {//调用钩子的set方法
return ret; } else {
elem.setAttribute( name, value + "" );//如果value是数值,隐式转为字符串
return value;
} } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {//调用钩子的get
return ret; } else {//取值
ret = jQuery.find.attr( elem, name );//调用Sizzle.attr 因为jquery中有一句:jQuery.find = Sizzle;
//将null值修正为undefined
// Non-existent attributes return null, we normalize to undefined
return ret == null ?
undefined :
ret;
}
}

从上面的代码看,有7个走向:

1、return

2、jQuery.prop

3、jQuery.removeAttr

4、attrHooks.set

5、elem.setAttribute

6、attrHooks.get

7、Sizzle.attr

前面5个都是设置值,6和7是读值。

2和3以后会读到,这里不提,先看看Sizzle.attr中是怎么一回事吧^^

    Sizzle.attr = function( elem, name ) {
// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {//如果不是当前document
setDocument( elem );//不知道干嘛 考虑iframe的情况?
} //Expr.attrHandle是一个对象,包含了
//async autofocus autoplay checked controls defer disabled hidden ismap loop
//multiple open readonly required scoped selected 等自定义方法(属性)
var fn = Expr.attrHandle[ name.toLowerCase() ],
// Don't get fooled by Object.prototype properties (jQuery #13807) //hasOwn 就是hasOwnProperty
//所以这个hasOwn.call( Expr.attrHandle, name.toLowerCase() ) 是在判断传入的属性名是不是这个对象的
//自定义属性,而不是原型上的属性
//val为调用自定义方法的结果或者undefined
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
fn( elem, name, !documentIsHTML ) :
undefined; //如果val为undefined
//如果(support.attributes为真或者document不是html),返回elem.getAttribute( name )的值
//否则 val为 elem.getAttributeNode(name))的值
//如果val为真,并且val.specified为真,返回val.value
//否则返回null
//否则返回val
return val === undefined ?
support.attributes || !documentIsHTML ?
elem.getAttribute( name ) :
(val = elem.getAttributeNode(name)) && val.specified ?
val.value :
null :
val;
};

复杂的三元运算符看得头都大了有木有,好吧,这里能看到,取值用getAttribute或者getAttributeNode。

再看attrHooks是一些什么内容:

    attrHooks: {
type: {
set: function( elem, value ) {
if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
// Setting the type on a radio button after the value resets the value in IE6-9
// Reset value to default in case type is set after value during creationvar val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
elem.value = val;
}
return value;
}
}
}
}

从这里可以看到,attrHooks与设置input标签的type值有关,恩,如果设置的值为radio的时候,注意下。

jQuery attr() 源码解读的更多相关文章

  1. jQuery.Callbacks 源码解读二

    一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...

  2. jQuery toggleClass 源码解读

    toggleClass: function( value, stateVal ) { var type = typeof value;//值类型 if ( typeof stateVal === &q ...

  3. jQuery removeAttr() 源码解读

    removeAttr比attr的代码要简单很多~~~ removeAttr: function( name ) { return this.each(function() { jQuery.remov ...

  4. jquery.fileupload源码解读笔记

    基础编程风格 新建 test.html  和 test.js和 main.js和 无论哪种顺序 <body> <script src="/Sandeep/js/jquery ...

  5. jQuery.extend()源码解读

    // extend方法为jQuery对象和init对象的prototype扩展方法// 同时具有独立的扩展普通对象的功能jQuery.extend = jQuery.fn.extend = funct ...

  6. jQuery框架源码解读

    1.jQuery 1.9.1 parseJSON: function( data ) { // Attempt to parse using the native JSON parser first ...

  7. jQuery position() 源码解读

    position的代码比较简单... position: function() { if ( !this[ 0 ] ) { return; } var offsetParent, offset, el ...

  8. jquery offsetParent()源码解读

    offsetParent: function() { return this.map(function() { var offsetParent = this.offsetParent || docE ...

  9. jQuery addClass() 源码解读

    addClass: function( value ) { var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = ...

随机推荐

  1. 初始化master节点时,日志内容分析

    root@master:~/code/shell# kubeadm init --image-repository registry.aliyuncs.com/google_containers ++ ...

  2. SpringInAction4笔记——装配

    重点:常用的上下文环境 AnnotationConfigApplicationContext ClassPathXmlApplicationContext FileSystemXmlApplicati ...

  3. <转载>调制与解调电路详解

    原文链接:http://www.elecfans.com/analog/20120509270848_4.html 调幅和检波电路 广播和无线电通信是利用调制技术把低频声音信号加到高频信号上发射出去的 ...

  4. goroutine pool,WaitGroup,chan 示例

    服务端高并发编程经常需要写很多goroutine来服务每一个连接,如何正确使用goroutine池是又拍云的工程师们需要考虑的问题,今天这篇文章,分享给同样需要使用go语言的小伙伴们. 文/陶克路 本 ...

  5. java邮件发送(含附件)

    1. [代码]java邮件发送(含附件)疯狂的IT人站长整理的:利用Java发送邮件(含附件)的例子:1.邮件发送的配置propertity文件内容如下:(utils.properties文件放在sr ...

  6. codeforces 437B. The Child and Set 解题报告

    题目链接:http://codeforces.com/contest/437/problem/B 题目意思:给出两个整数 sum 和 limit,问能否从1 - limit 这些数中选出一些数(注意: ...

  7. html5--6-11 CSS选择器7--伪类选择器

    html5--6-11 CSS选择器7--伪类选择器 #E:target 选择当前活动的锚点元素. 学习要点 掌握常用的CSS选择器 了解不太常用的CSS选择器 什么是选择器 当我们定义一条样式时候, ...

  8. mongodb c++ driver安装踩坑记

    安装教程:https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/installation/ (1) “initializer_list” fil ...

  9. Python里的一些注释规范

    写代码注释是一件很重要的事情,如果你写的一段函数给别人调用那么往往都需要配上一些基本的注释.写好代码可以让别人容易阅读你的代码.试想一 下:如果你在github上面找到一段你想要的代码,这段代码有20 ...

  10. HBase之一:HBase原理和设计

    一.简介 HBase —— Hadoop Database的简称,Google BigTable的另一种开源实现方式,从问世之初,就为了解决用大量廉价的机器高速存取海量数据.实现数据分布式存储提供可靠 ...