jQuery提供了一些快捷函数来对dom对象的属性进行存取操作. 这一部分还是比较简单的.

根据API这章主要是分解5个方法

  • .attr()   获取匹配的元素集合中的第一个元素的属性的值  或 设置每一个匹配元素的一个或多个属性。
  • .prop() 获取匹配的元素集中第一个元素的属性(property)值或设置每一个匹配元素的一个或多个属性。
  • .removeAttr() 为匹配的元素集合中的每个元素中移除一个属性(attribute)。
  • .removeProp() 为集合中匹配的元素删除一个属性(property)。
  • .val() 获取匹配的元素集合中第一个元素的当前值或设置匹配的元素集合中每个元素的值

jQuery的主要工作还是为了解决浏览器的兼容性. 这部分的方法一般都有2个特点.

  • set方法和get方法一体化. 根据参数数量来判断是set还是get.
  • value可以传入一个闭包. 这个闭包的返回值才是真正的value.

先看一组HTML结构

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

用attr,与prop取值出input元素上的checked

分别会取得什么值?

$('input').attr('checked')  //checked 

$('input').prop('checked')  // true

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


attribute和property的区别

attribute:特性

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

property:属性

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

观察一张图很直观的理解:

attributes是一个类数组的容器,说得准确点就是NameNodeMap,总之就是一个类似数组但又和数组不太一样的容器。attributes的每个数字索引以名值对(name=”value”)的形式存放了一个attribute节点。

attributes是会随着添加或删除attribute节点动态更新的。

特性的操作:

  • getAttribute
  • setAttribute
  • removeAttribute

property就是一个属性,如果把DOM元素看成是一个普通的Object对象,那么property就是一个以名值对(name=”value”)的形式存放在Object中的属性。要添加和删除property也简单多了,和普通的对象没啥分别。

之所以attribute和property容易混倄在一起的原因是,很多attribute节点还有一个相对应的property属性

DOM元素一些默认常见的attribute节点都有与之对应的property属性,比较特殊的是一些值为Boolean类型的property,如一些表单元素。

总的来说:基本可以总结为attribute节点都是在HTML代码中可见的,而property只是一个普通的名值对属性


  • jQuery.prototype.attr
  • jQuery.prototype.prop
  • jQuery.prototype.removeAttr
  • jQuery.prototype.removeProp
  • jQuery.prototype.val

jQuery把又长又难记的函数用外观模式包装成attr,prop,内部setAttribute,getAttribute是低级API,实现核心功能, 从而隐藏了用户程序对jQuery各个模块调用的复杂性

看看源码的实现

attr: function( ele, value ) {
return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
},
prop: function( name, value ) {
return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
},

暴露给api的原型方法非常简单,只有一句话.把参数交给jQuery.access函数去处理. jQuery.access主要作用是修正参数.

access函数里的第二个参数jQuery.attr. 这个参数的作用是告诉access方法, 修正完参数后再去调用 jQuery.attr方法.

access方法是可以被抽象出复用的一组对参数的修正方法,通过分解成单一的数据后,然后调用传递的回调处理钩子 比如 attr,css, prop.等等

jQuery.access源码	// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
var i = 0,
length = elems.length,
bulk = key == null; // Sets many values
if ( jQuery.type( key ) === "object" ) { //传递是对象
chainable = true;
for ( i in key ) { //递归调用
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
} // Sets one value
} else if ( value !== undefined ) {
chainable = true; if ( !jQuery.isFunction( value ) ) {
raw = true;
} if ( bulk ) {
// Bulk operations run against the entire set
if ( raw ) {
fn.call( elems, value );
fn = null; // ...except when executing function values
} else {
bulk = fn;
fn = function( elem, key, value ) {
return bulk.call( jQuery( elem ), value );
};
}
} if ( fn ) {
for ( ; i < length; i++ ) {
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
}
}
} return chainable ?
elems : // Gets
bulk ?
fn.call( elems ) :
length ? fn( elems[0], key ) : emptyGet;
},

access源码部分比较简单, 就是对象传参分解成单一的参数从而set,get处理


关于jQuery Hooks

你知道一些核心jQuery函数都有自己的“插件API”称为“钩子”?

详见:http://blog.rodneyrehm.de/archives/11-jQuery-Hooks.html

大概意思如下:

jQuery提供一个API来调用用户自定义的函数,用于扩展,以便获取和设置特定属性值

主要是:.attr(), .prop(), .val() and .css()四种类型的处理

钩子都有相似的结构

var someHook = {
get: function(elem) {
// obtain and return a value
return "something";
},
set: function(elem, value) {
// do something with value
}
}

如何使用?

用jQuery官方提供的为列 http://www.css88.com/jqapi-1.9/jQuery.cssHooks/

在做css3属性浏览器兼容的时候,都需要特定的前缀

Webkit的浏览器:-webkit-border-radius

Firefox:-moz-border-radius

此时我看可以采用一个CSS hook 可以标准化这些供应商前缀的属性,让.css() 接受一个单一的,标准的属性的名称(border-radius,或用DOM属性的语法,borderRadius

判断的代码省略,直接看实现

给某一元素设置borderRadius,为10px

$("#element").css("borderRadius", "10px");

为了做浏览器兼容,我们不得不

if(webkit){
........................
}else if(firefox){
............................
}else if(...)更多

这是一种最没技术含量的写法了,如果我们换成一种hook的话

$.cssHooks.borderRadius = {
get: function( elem, computed, extra ) {
return $.css( elem, borderRadius );
},
set: function( elem, value) {
elem.style[ borderRadius ] = value;
}
};

borderRadius = styleSupport( "borderRadius" ); //获取到相对应的浏览器标准

这里可能还不直观的体现,我们深入到attr源码中看看


jQuery.attr 静态方法

jQuery实例的方法都是调用最终的静态方法:jQuery.attr

access函数最后把参数又传递给了jQuery.attr, 在jQuery.attr里才真正进行setAttribute/getAttribute操作.

查看源码关于attrHooks一个type

意思就是在使用attr(‘type’,??)设置的时候就会调用这个hooks,用于处理IE6-9 input属性不可写入的问题

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 creation
var val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
elem.value = val;
}
return value;
}
}
}
},

省略部分代码attr源码

  • 通过hooks = jQuery.attrHooks[ name ]方法,去适配对应的name,是否在合集中
  • 如果是hooks然后又是get方法就调用 hooks && "set" in hooks && (ret = hooks.set( elem, value, name )
  • 如果有ret返回值就return(hooks.set可能还不是最终匹配)
  • 否则继续往下走

其实这样的思路,在sizzle选择器也大量的运用了

钩子就是适配器原理,用来处理一些特殊的属性,样式或事件。而这些属性,样式或事件,我们可以通过浏览器的特征嗅探,把相应的解决方法添加到适配器中。有了这些适配器,jQuery就可以省去许多if else 判定


那么,利用钩子处理兼容与扩展的好处:

  • 适配器这种模式对于扩展新功能非常有利
  • 如果采用钩子处理的话,我们就省去了一大堆if else的分支判断
  • 由于JS用对象做为表进行查找是比if条句与switch语句快很多

本章的重点在于如何灵活运用运用钩子的原理,在实际项目中更好的处理兼容与扩展

jQuery 2.0.3 源码分析 钩子机制 - 属性操作的更多相关文章

  1. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

  2. jQuery 2.0.3 源码分析 Deferred(最细的实现剖析,带图)

    Deferred的概念请看第一篇 http://www.cnblogs.com/aaronjs/p/3348569.html ******************构建Deferred对象时候的流程图* ...

  3. jQuery 2.0.3 源码分析core - 选择器

         声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢!      打开jQuery源码,一眼看去到处都充斥着正则表达式,jQuery框架的基础就是查询了,查询文档元素对象 ...

  4. jQuery 2.0.3 源码分析 Deferred概念

    JavaScript编程几乎总是伴随着异步操作,传统的异步操作会在操作完成之后,使用回调函数传回结果,而回调函数中则包含了后续的工作.这也是造成异步编程困难的主要原因:我们一直习惯于“线性”地编写代码 ...

  5. jQuery 2.0.3 源码分析 事件绑定 - bind/live/delegate/on

    事件(Event)是JavaScript应用跳动的心脏,通过使用JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应 事件的基础就不重复讲解了,本来是定位源码分析 ...

  6. jQuery 2.0.3 源码分析 事件体系结构

    那么jQuery事件处理机制能帮我们处理那些问题? 毋容置疑首先要解决浏览器事件兼容问题 可以在一个事件类型上添加多个事件处理函数,可以一次添加多个事件类型的事件处理函数 提供了常用事件的便捷方法 支 ...

  7. jQuery 2.0.3 源码分析 Deferrred概念

    转载http://www.cnblogs.com/aaronjs/p/3348569.html JavaScript编程几乎总是伴随着异步操作,传统的异步操作会在操作完成之后,使用回调函数传回结果,而 ...

  8. jQuery 2.0.3 源码分析 样式操作

    根据API分类 CSS addClass() jQuery.cssHooks .hasClass() .removeClass() .toggleClass() .addClass() 对元素的样式操 ...

  9. jQuery 2.0.3 源码分析core - 整体架构

    拜读一个开源框架,最想学到的就是设计的思想和实现的技巧. 废话不多说,jquery这么多年了分析都写烂了,老早以前就拜读过, 不过这几年都是做移动端,一直御用zepto, 最近抽出点时间把jquery ...

随机推荐

  1. Chrome一直提示“adobe flash player 因过期而遭阻止” ,如何解决?

    完全不用安装最新版的 Chrome,只需要将 Flash 组件安装一下最新版即可. 并且这里需要的不是网上随处可见的 NPAPI 版本,而是冷门的 PPAPI 版本. 请收藏好这个链接,是某位大牛从 ...

  2. The World's Only Advanced Operating System

    The World's Only Advanced Operating System

  3. MariaDB 主从复制的配置

    一.安装MariaDB 安装过程省略. 二.主从配置 环境     Master/Slave     系统 IP 数据库版本 Master     CentOS6.7         10.10.3. ...

  4. [资源分享]yslow 与firebug 修复版本Firefox35【绿色版本下载】

    自从火狐也开始做版本帝后,相关查的插件越来越不好使了, 而且火狐集成自己的调试工具,也不是很好使用,Yslow 也坏掉了 找公司写c++修复了下 把yslow和Firebug 打包到一起,而且关闭自动 ...

  5. bzoj1266最短路+最小割

    本来写了spfa wa了 看到网上有人写Floyd过了 表示不开心 ̄へ ̄ 改成Floyd试试... 还是wa ヾ(。`Д´。)原来是建图错了(样例怎么过的) 结果T了 于是把Floyd改回spfa 还 ...

  6. 插头dp

    插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...

  7. 利用CORS实现跨域请求(转载)

    跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一问题.不过现在,我们可以考虑一下W3C中一项新的特性--CORS(Cross-Origin Resource Sh ...

  8. DoD and DoR

    Definition of Ready User Story is defined Acceptance criteria(functional and non-functional requirem ...

  9. List、Map、Set三个接口,存取元素时,各有什么特点?

    List  以特定次序来持有元素,可有重复元素:Set  无法拥有重复元素,内部排序(无序):Map 保存key-value值,value可多值.

  10. Javascript初学篇章_6(BOM)

    BOM 浏览器对象模型 BOM (浏览器对象模型),它提供了与浏览器窗口进行交互的对象 一.window对象 Window对 象表示整个浏览器窗口. 1.系统消息框 alert() alert('he ...