jQuery 源码解析代码及更多学习干货: 猛戳GitHubhtml
建议下载源码而后据文章思路学习,最好本身边思考边多敲几遍。前端
myjQuery-1.0.1.js
(这个文件是用来仿写jQuery).myjQuery-1.0.1.js
文件.本次主要剖析jQuery选择器的封装,在平时使用jQuery时,很是容易的经过$()就能够查找相关的选择器,那么具体是如何实现的呢?跟随我来一探究竟...node
首先先来作个例子: 咱们先经过官方的jQuery框架输出如下几个实例:jquery
// 传入字符串
console.log($("a")); //建立DOM节点包装成jQuery对象
// 传入HTML
console.log($("<div>")); // //建立DOM节点包装成jQuery对象
// 传入对象
console.log($(document));
// 传入选择器
console.log($('.box'));
// 传入对象
console.log($(this)); // 把传入的对象包装成jQuery对象
// 传入方法
$(function(){
console.log(11111); //这个是在页面加载完成后加载执行的,等效于在DOM文档加载完成后执行了$(document).read()方法
})
复制代码
输出结果:git
init:function (selector,context) {
context = context || document;
var match,elem,index=0;
if(!selector){
return this;
}
/**
* 检测传过来的数据是不是字符串
* **/
if(typeof selector === "string"){
if (selector.charAt(0) === "<" && selector.charAt(selector.length-1)=== ">" && selector.length>=3) {
// 此时是HTML
match = [selector];
}
// match 有值的状况
if (match) {
/**
* 合并数组
* merge parseHTML是静态扩展方法
* **/
jQuery.merge(this, jQuery.parseHTML(selector,context));
// 查询DOM节点
} else {
elem = document.querySelectorAll(selector);
// 转化为真数组
var elems = Array.prototype.slice.call(elem);
this.length = elem.length;
for (;index = elem.length;index ++) {
this[index] = elems[index];
}
this.context = context;
this.selector = selector;
}
// HANDLE: $(DOMElement)
} else if (selector.nodeType){ //
this.context = this[0] = selector;
this.length = 1;
return this;
// $(function)
// 函数处理
} else if (isFunction( selector )) {
jQuery(document).ready(selector); // 实例对象的方法
}
/**
*makeArray 是jQuery扩展的方法
**/
return jQuery.makeArray( selector, this );
},
复制代码
jQuery 扩展的静态方法
/**
* 合并数组
* [first] jQuery的实例对象 this
* [second] DOM 节点
*/
merge:function (first,second) {
var l = second.length, // 1
i = first.length, // 0
j = 0;
if (typeof l === "number") {
for ( ; j < l; j++){ // 遍历DOM节点
first[i++] = second[j];
}
} else {
while (second[j] !== undefined) {
first[i++] = second[j++];
}
}
first.length = i;
// 返回jQuery的实例对象
return first;
},
/**
* 解析HTML
* [data] 传入的数据
* [context] 返回的值
* **/
parseHTML:function (data,context) {
if (!data || typeof data !== "string") {
return null;
}
/**
* exec() 是正则方法 返回为数组
* [0] 为正则表达式相匹配的文本
* [1] 表达式相匹配的文本
* **/
// 过滤掉符号,只提取标签 "<a>" ==> "a"
var parse = rejectExp.exec(data);
// 返回一个建立DOM的元素
return [context.createElement(parse[1])];
},
/**
* 将一个类数组对象转换为真正的数组对象
* [arr] 传入的数组
* [result] 返回的数组
* **/
makeArray:function(arr,result){
var ret = result || [];
if ( arr != null ) {
if ( isArrayLike( Object( arr ) ) ) {
jQuery.merge( ret,
typeof arr === "string" ?
[ arr ] : arr
);
} else {
[].push.call( ret, arr );
}
}
return ret;
},
isReady:false,
readylist:[],// list
ready:function(){ // 事件函数
jQuery.isReady = true;
jQuery.readylist.forEach(function(callback){
callback.call(document);
})
// 清空
jQuery.readylist = null;
}
});
复制代码
/**
* 定义全局函数
* **/
// 判断是不是方法
var isFunction = function isFunction( obj ) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
// 判断是不是windows
var isWindow = function isWindow( obj ) {
return obj != null && obj === obj.window;
};
复制代码
经过以上代码能够作如下几点分析:
1.$()传过来的selector数据是属于什么类型?不一样的数据类型,分析不一样数据类型的行为,有如下几种状况:
github
经过剖析jQuery选择器模块,进行测试:正则表达式
测试代码:windows
// 建立DOM
// 传入字符串
console.log($("a")); //建立DOM节点包装成jQuery对象
// 传入HTML
console.log($("<div>")); // //建立DOM节点包装成jQuery对象
// 传入对象
console.log($(document));
// 传入选择器
console.log($('.box'));
// 传入对象
console.log($(this)); // 把传入的对象包装成jQuery对象
$(function(){
console.log(11111);
复制代码
输出结果:设计模式
经过剖析jQuery源码选择器部分,有如下几点我的收获:
数组
jQuery 源码剖析 系列目录地址:猛戳GitHub
jQuery 源码剖析 系列预计写十篇左右,旨在加深对原生JavaScript 部分知识点的理解和深刻,重点讲解 jQuery核心功能函数、选择器、Callback 原理、延时对象原理、事件绑定、jQuery体系结构、委托设计模式、dom操做、动画队列等。
若是有错误或者不严谨的地方,请务必给予指正,十分感谢。若是喜欢或者有所启发,欢迎 star⭐️,对做者也是一种鼓励。
关注公众号回复:学习 领取前端最新最全学习资料,也能够进群和大佬一块儿学习交流