jQuery晦涩的底层工具方法们
这里整理的是jQuery源码中一些比较晦涩难懂的、内部的、最底层的工具方法,它们多为jQuery的上层api方法服务,目前包括:
- jQuery.access
jQuery.access: function( elems, fn, key, value, chainable, emptyGet, pass )
在jQuery的众多api方法中,许多方法都有一个非常重要和常见的特征:重载,简单来讲即参数的不同决定了方法的功能不同
例如我们最常使用的几个:jQuery.fn.html()、jQuery.fn.attr()、jQuery.fn.text()、jQuery.fn.css()等等
从这些方法的身上,我们其实可以总结出它们之间一些共同具有的特征:
- 所有的操作都是在元素节点上
- 进行的操作都是get或set
- 都有自己的处理函数
- 都可以接受函数作为参数干预最终的结果
- 具备链式调用的能力
源码解析:
// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
/** 参数说明
* elems [object] 元素
* fn [function] 原始处理函数
* key [string|object] 属性名称/键值对列表
* value [type|function] 进行赋值的值/干预函数
* chainable [boolean] 是否可以链式调用
* emptyGet [type] 指定的空值,类型不定
* pass [boolean] 属性与jQuery方法同名时,是否调用jQuery的方法,在attr方法那里会用到
*/
access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
var exec,
bulk = key == null,
i = 0,
length = elems.length; // Sets many values
// 如果key是一个键值对对象,那么一定是在赋值,分解key然后递归调用
if ( key && typeof key === "object" ) {
for ( i in key ) {
// 可以看出,赋值操作都是可以继续链式调用,因为chainable直接被赋值为了1
jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
} // 这里仍然需要手动设置chainable的值为1
// 因为这里并没有return
chainable = 1; // Sets one value
} else if ( value !== undefined ) {
// Optionally, function values get executed if exec is true
// 如果没传pass并且传入了干预函数
exec = pass === undefined && jQuery.isFunction( value ); // bulk = key == null
// 即没有传入key,但传了value进来
if ( bulk ) {
// Bulk operations only iterate when executing function values
// value是个函数的情况
if ( exec ) {
// 原始处理函数用exec保存起来
exec = fn;
// 把原本保存原始处理函数的变量fn重新用约定好的结构进行封装,以便后面统一进行调用
// 这里的key参数纯粹是为了在后面的调用处统一参数
// 注意这里的fn函数最后返回了原始处理函数的处理结果,为什么这样做呢?后面解释
fn = function( elem, key, value ) {
return exec.call( jQuery( elem ), value );
}; // Otherwise they run against the entire set
} else {
// 这是最简单的情况,直接调用原始处理函数进行赋值
// 这种情况下的赋值操作到这里就已经完成了
// 所以在这里把fn置为了null,因为后面的if已经没有必要执行了
fn.call( elems, value );
fn = null;
}
} // 剔除上面最简单那种情况,无论传不传key的值,这里的if都会执行
if ( fn ) {
for (; i < length; i++ ) {
// 这里的fn的值包含两种情况,一个是原始处理函数,一个是上面已经封装过的fn
// 这里最难理解的应该就是fn( elems[i], key )这句话了
// 首先无论是哪种情况,fn( elems[i], key )这句话一定是一个取值的操作
// 那么如果fn是原始处理函数,并且传入了key的值,取到的其实就是这个元素的原始属性值,把它作为第二个参数传入了干预函数
// 如$("div").attr( "id", function( index, attr ){} )
// 如果fn是上面封装的函数,表示没有传入key值,则fn中的key和value都是undefined,但仍然仅凭元素就可以取得这个元素的原始属性值,哪种情况呢?
// 如$("div").text("something")
// 所以,fn( elems[i], key )这句话的作用也就清晰了,就是取得元素的原始属性值
// 搞懂了上面,这行代码也就不难理解了,这里设计的确实是巧啊
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
}
} // 同样,仍然是可以链式调用
chainable = 1;
} // 如果可以链式调用,返回元素集即可,函数到此结束
// 如果不是,则证明是在取值
// 如果没传key,直接返回fn.call( elems ),如$("div").html()
// 如果传了key,则返回第一个元素的key对应的属性值或返回指定的空值emptyGet
return chainable ?
elems : // Gets
bulk ?
fn.call( elems ) :
length ? fn( elems[0], key ) : emptyGet;
}
jQuery晦涩的底层工具方法们的更多相关文章
- JQuery --- 第一期 (初识jQuery, JQuery核心函数和工具方法)
个人学习笔记 初识jQuery 1.我的第一个JQuery <!DOCTYPE html> <html lang="en"> <head> & ...
- jQuery源代码 解析一 工具方法
1. 外层沙箱以及命名空间$ 几乎稍微有点经验前端人员都这么做,为了避免声明了一些全局变量而污染,把代码放在一个"沙箱执行",然后在暴露出命名空间(可以为API,函数,对象): 2 ...
- JQuery $ $.extend(),$.fn和$.fn.extend javaScript对象、DOM对象和jQuery对象及转换 工具方法(utility)
一.为什么jquery前面要写$ Javascript没有package的概念,而作者又希望所有jQuery相关的API都能通过一个全局性的对象来容纳. 名为jQuery的全局变量就是这样一个对象,不 ...
- JavaScript1.6数组新特性和JQuery的几个工具方法
JavaScript 1.6 引入了几个新的Array 方法,具体的介绍见:New in JavaScript 1.6 .这些方法已经被写进了ECMA262 V5.现代浏览器(IE9/Firefox/ ...
- JQuery extend()与工具方法、实例方法
使用jQuery的时候会发现,jQuery中有的函数是这样使用的: $.get(); $.post(); $.getJSON(); 有些函数是这样使用的: $('div').css(); $('ul' ...
- JQuery操作类数组的工具方法
JQuery学习之操作类数组的工具方法 在很多时候,JQuery的$()函数都返回一个类似数据的JQuery对象,例如$('div')将返回div里面的所有div元素包装的JQuery对象.在这中情况 ...
- jQuery工具方法
目录 常用工具方法 判断数据类型的方法 Ajax操作 $.ajax 简便写法 Ajax事件 返回值 JSONP 文件上传 参考链接 jQuery函数库提供了一个jQuery对象(简写为$),这个对象本 ...
- jQuery常用工具方法
前面的话 jQuery提供一些与元素无关的工具方法,不必选中元素,就可以直接使用这些方法.如果理解原生javascript的继承原理,那么就能理解工具方法的实质.它是定义在jQuery构造函数上的方法 ...
- jquery中的工具方法$.isFunction, $.isArray(), $.isWindow()
本文正式地址:http://www.xiabingbao.com/jquery/2015/07/25/jquery-judge-type 在javascript中对变量类型的判断中,我们讲解了了jqu ...
随机推荐
- jqgrid 中的事件
1. var obj = $("#tablename").jqGrid("getRowData"); 取得所有的行 alert(obj.length); ...
- C++标准库 -- pair
头文件:<utility> 可访问属性: first 第一个值 second 第二个值 可访问方法: swap(pair) 和另外一个pair交换值 其他相关方法: make_pair(v ...
- 【转发】关于Java性能的9个谬论
转载请注明出处,感谢大家的支持!本文来自优优码:http://www.uucode.net/201502/9%e4%b8%aa%e8%b0%ac%e8%ae%ba Java的性能有某种黑魔法之称.部分 ...
- CPP - sort
#include "stdafx.h" #include <iostream> #include <string> using namespace std; ...
- 使用git@osc管理现有项目
首先安装git和powershell集成git工具 参考 http://www.cnblogs.com/kreo/p/4685988.html 打开windows powershell,进入项目目录, ...
- JMeter学习-033-JMeter BeanShell 脚本应用实例之参数变量修改
BeanShell脚本是JMeter自动化测试过程中不可或缺的提升技能之一,BeanShell脚本编写类似于Java脚本.它可以获取.修改系统定义或用户定义的变量值,同时也可以进行一些相应的测试数据处 ...
- ubuntu14.0 (arm平台)源码安装 VLC播放器
环境 ubuntu14.0 arm开发板 源 deb http://mirrors.ustc.edu.cn/ubuntu-ports/ trusty main multiverse restrict ...
- Docker应用程序容器技术_转
转自:百度百科 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相 ...
- Django补充及初识Ajax
Django创建一对多表结构 首先现在models.py中写如下代码: from django.db import models # Create your models here. class Bu ...
- echarts基础 handleIcon 设置
1.自己引入echarts库 2.找到代码中dataZoom中的handleIcon ,看见对应的是"M0,0 v9.7h5 v-9.7h-5 Z",这是由svg画出来的图形,其中 ...