jQuery方法源码解析--jQuery($)方法(一)
注:
1.本文分析的代码为jQuery.1.11.1版本,在官网上下载未压缩版即可
2.转载请注明出处
$( "span", this ).addClass( "bar" );
});
element :Element
.data(),.prop(),.on(), .off(), .trigger() and .triggerHandler().
The use of .data() (or any method requiring .data()) on a plain object will result in a new
property on the object called jQuery{randomNumber} (eg. jQuery123456789).
$()
function, a clone of the object is created. This new jQuery object references the same DOM elements as the initial one.
"class": "my-div",
on: {
touchstart: function( event ) {
// Do something}
}}).appendTo( "body" );
$( "<div></div>" )
.addClass( "my-div" )
.on({
touchstart: function( event ) {
// Do something
}
})
.appendTo( "body" );
what is jQuery Object??
<ol>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</body>
![](/assets/blank.gif)
总结一下,jQuery对象,就是在js对象的基础上,包装了一些jQuery方法的对象,有一个英文词形容的比较贴切,就是wrap(包裹).
jQuery方法的结构
在jQuery1.11.1的源码中,搜索jQuery,在源码开始的不远处,就可以看到如下的代码:
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
}
我们搜一下jQuery.fn.init这货:
var match, elem;
init.prototype = jQuery.fn;
jquery.init方法
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/
console.log(rquickExpr.exec("<tag>"));
init = jQuery.fn.init = function( selector, context ) {var match, elem;//处理jQuery()形式,返回空的jQuery对象// HANDLE: $(""), $(null), $(undefined), $(false)if ( !selector ) {return this;}// Handle HTML strings/*#源码分析*匹配html(以<开头,以>结尾,或者是<tag>...形式,推荐写严格的html),或者是#id形式,并且确保,#id情况下,没有context*/if ( typeof selector === "string" ) {if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {/*#源码分析*假设以<开头,以>结尾的,并且长度大于3的String都是htmlString,然后存到match中*/// Assume that strings that start and end with <> are HTML and skip the regex checkmatch = [ null, selector, null ];} else {match = rquickExpr.exec( selector );}/*#源码分析*what is match?*我们分析过rquickExpr这个正则表达式,它有两个分组(最外面的那个分组不捕获,没算),*这样使用exec方法后,如果匹配到了,则应该返回一个长度为3,包括index和input属性的数组。*那么match[0]是整体匹配的数组,match[1]是匹配的<tag>标签(如果有),match[2]匹配#id(如果有)*显然match[1],match[2]只能有一个被捕获*/// Match html or make sure no context is specified for #idif ( match && (match[1] || !context) ) {//处理jQuery( html [, ownerDocument ] ),根据html生成dom元素,返回jQuery对象,就像下面的注释$(html) -> $(array)//match[1]// HANDLE: $(html) -> $(array)if ( match[1] ) {/*#源码分析*如果context是jQuery对象,转为js原生对象.*我们说过,jQuery对象就是给js原生对象包装了了一些方法的对象,而原生对象以类数组的形式存在jQuery中,*所以context[0],就是去jQuery对象中的第一个原生对象,在这里context期待传入的就是document或者$(document)*/context = context instanceof jQuery ? context[0] : context;/*#源码分析*这里调用了jQuery.parseHTML方法,就是把htmlString转为dom数组*还调用了jQuery.merge(first,second),接收两个"类数组"参数,*这个方法是把第二个数组追加到第一个数组尾部,会改变第一个数组*前面讲过,jQuery对象具有类数组结构,当前还没有操作this,它的length = 0*所以下面这段代码,就是把htmlString转为dom数组并追加到this的尾部。*/// scripts is true for back-compat// Intentionally let the error be thrown if parseHTML is not presentjQuery.merge( this, jQuery.parseHTML(match[1],context && context.nodeType ? context.ownerDocument || context : document,true) );/*#源码分析*处理jQuery( html, attributes )这种用法*第一个参数必须是单标签,第二个参数是一个普通对象,类似{html:"hello world",id:"test"}*注意,这种情况下,会走上面的分支,已经把单标签转为dom并拼接到了this中了*/// HANDLE: $(html, props)if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {for ( match in context ) {/*#源码分析*这里的match是context的属性*如果有match的方法,就会调用match方法*比如{html:"hello world",id:"test"},就会调用this.html("hello world")方法*否则按照属性处理*/// Properties of context are called as methods if possibleif ( jQuery.isFunction( this[ match ] ) ) {this[ match ]( context[ match ] );// ...and otherwise set as attributes} else {this.attr( match, context[ match ] );}}}return this;/*#源码分析*处理match[2]被捕获到的情况,也就是#id的情况*/// HANDLE: $(#id)} else {elem = document.getElementById( match[2] );// Check parentNode to catch when Blackberry 4.6 returns// nodes that are no longer in the document #6963// 为了兼容Blackberry 4.6中的一个bug,不但判断element,还要判断elem.parentNodeif ( elem && elem.parentNode ) {// Handle the case where IE and Opera return items// by name instead of ID/*#源码分析*早期的IE的document.getElementById()有bug,在查找元素时,会把表单的元素的name也看成是id,*这时候使用find方法来兼容,搜索一下"rootjQuery =",会发现rootjQuery = jQuery( document );*/if ( elem.id !== match[2] ) {return rootjQuery.find( selector );}/*#源码分析*否则直接放到this[0]中*/// Otherwise, we inject the element directly into the jQuery objectthis.length = 1;this[0] = elem;}this.context = document;this.selector = selector;return this;}/*#源码分析*处理$(复杂选择器的情况),采用find方法处理并返回,*这里两个else的判断,就是为了确保是jQuery对象调用find方法,*如果context不是jQuery对象,使用constructor构造一个*context.jquery-->jquery是jQuery.fn上的一个版本属性,在此用这个来判断是否是jQuery对象。*/// HANDLE: $(expr, $(...))} else if ( !context || context.jquery ) {return ( context || rootjQuery ).find( selector );// HANDLE: $(expr, context)// (which is just equivalent to: $(context).find(expr)} else {return this.constructor( context ).find( selector );}/*#源码分析*else selector不是String类型的*/// HANDLE: $(DOMElement)} else if ( selector.nodeType ) {/*#源码分析*处理$(DOMElement)形式,这个比较简单,就是加到this[0]上*/this.context = this[0] = selector;this.length = 1;return this;// HANDLE: $(function)// Shortcut for document ready} else if ( jQuery.isFunction( selector ) ) {/*#源码分析*$(function)形式,就是调用了$(document).ready()方法*/return typeof rootjQuery.ready !== "undefined" ?rootjQuery.ready( selector ) :// Execute immediately if ready is not presentselector( jQuery );}/*#源码分析*如果selector.selector !== undefined,那么selector本身可能就是一个jQuery对象,做了如下处理,为什么呢?!不知道*/if ( selector.selector !== undefined ) {this.selector = selector.selector;this.context = selector.context;}/*#源码分析*jQuery.makeArray(arr)是把类数组,转为纯数组形式,API是这么说的.*实际上makeArray还有第二个参数,但仅限内部使用,就是现在这种情况*jQuery.makeArray( arr, results ) -->把调用jQuery.merge把arr数组追加到results尾部*这里会处理jQuery( elementArray )、jQuery( object )这两种情况*/return jQuery.makeArray( selector, this );
};
jQuery方法源码解析--jQuery($)方法(一)相关推荐
- 【Android 异步操作】线程池 ( 线程池 execute 方法源码解析 )
文章目录 一.线程池 execute 方法源码解析 二.线程池 execute 方法完整源码及注释 一.线程池 execute 方法源码解析 进入 ThreadPoolExecutor 中 , 查看线 ...
- erlang下lists模块sort(排序)方法源码解析(二)
上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...
- Spring 注解面面通 之 @CrossOrigin 注册处理方法源码解析
参照<Spring 注解面面通 之 @RequestMapping 注册处理方法源码解析>,其讲解了@RequestMapping注释的处理方法注册过程,而@CrossOrigin是基 ...
- Intent.createChooser方法源码解析(按我的解析,只有一个Intent是不会启动的??Android源码7.1.2)
参考: https://www.geek-share.com/detail/2631984744.html https://tuzhao.org/article/34#directory0136555 ...
- ReentrantLock acquire方法源码解析
public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCL ...
- Arrays.asList()方法源码解析
asList public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表.(对返回列表的更改会"直接写& ...
- HashMap::put方法源码解析及执行流程图
HashMap::put方法 类介绍: HashMap 是Java的一个集合类,继承了AbstractMap类,同时实现了Map.Cloneable.Serializable接口 public c ...
- 工厂方法源码解析(jdk+logback)
我们来看一下Collection,这个类大家都比较熟悉,public interface Collection<E> extends Iterable<E> {是集合类,例如在 ...
- BufferedInputStream的read()方法源码解析
BufferedInputSream默认是现实给出了一个8192byte大小的数组. private static int DEFAULT_BUFFER_SIZE = 8192;public Buff ...
最新文章
- 有多少智能,就有多少人工?人工智能背后的数据标注师
- ESP32 flash容量配置
- tensorflow怎样调用gpu_tensorflow / tensorflow-gpu / tensorflow-cpu区别?
- 七十、SpringBoot整合 Druid数据源
- 列举6个常见且实用的Web前端性能优化方法
- 【莫队】区间众数(Codeforces Round #716 (Div. 2) D)
- oracle log.xml分析,Oracle 11g Alert Log日志位置及参数
- python迭代器和生成器_Python迭代器与生成器
- 华为OJ之奥运会金牌排名显示国家名称
- 计算机无法识别外接光驱,USB外置光驱不能用怎么办 USB外置光驱无法识别解决方法...
- No3 jQuery
- 以太网芯片mac/phy的关系
- Design the Web: Add a Twitter Timeline 设计网页:添加Twitter时间轴 Lynda课程中文字幕
- MySQL:由于找不到VCRUNTIME140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题
- 检查nmos管是否损坏
- 释万行上师:罕见的修行真相揭秘【全】
- 爬虫第八式:破解百度翻译案例(特别详细) - JS逆向
- 【工具】fis3 - 使用教程(01)
- 清华同方的计算机硬件设置,清华同方笔记本电脑开机进入BIOS的几种方法(F2)附bios设置图文方...
- MyDockFinder 5.5体验极致模拟 Mac OS 系统桌面,完美支持最新版Win10 系统,可使用系统级模糊效果