jQuery源码解析(架构与依赖模块)一、理解架构

一、设计原理

轻量级的js库,兼容CSS3,兼容各种浏览器(IE6.0+,FF1.5+,Safari2.0+,Opera9.0+),Jquery2.0及后续潘奔不在支持IE6/7/8浏览器。jQuery一个比较大的优势是,它的文档说明很全,并且各种应用很详细,同时还有许多成熟的插件提供。核心:The Write Less,Do More(写更少,做更多)。简洁的API、优雅的链式、强大的查询与便捷的操作,使的jQuery成为前端世界的一把利剑!

二、整体架构

13个核心方法
// 核心方法
// 回调系统
// 异步队列
// 数据缓存
// 队列操作
// 选择器引
// 属性操作
// 节点遍历
// 文档处理
// 样式操作
// 属性操作
// 事件体系
// AJAX交互
// 动画引擎
五大模块:
选择器、DOM操作、事件、AJAX与动画

三、立即调用表达式

任何库和框架设计第一要点就是解决命名空间与变量污染的问题,jQuery利用了JS函数作用于的特性,采用‘立即调用表达式’包裹了自身的方法来解决这个问题。

写法1.

(function (window,factory) {
		factory(window);
	}(this,function () {
		return function () {
			//jQuery的调用
			alert(12);
		}	
	}));


形参 window和factory,实参this、函数,factory(window)中的window为一个实参,this代表window
上面的代码代码代码中嵌套了两个函数,把其中的一个函数作为参数传递到另一个函数中,并且执行,我们可以简化一下写法:如下

写法2.

var factory = function () {
		return function () {
			//执行方法
			alert(12);
		}
	};
	var jQuery = factory(); //此时表达的是返回的函数

上面的代码效果和方法一是等同的,但是却有点变成了简单的工厂方法模式,需要自己去调用,下面我们再次改进:

写法3.

(function (window,undefined) {
		var jQuery = function () {}
			// ...
			window.jQuery = window.$ = jQuery;
				$();
	})(window);

四、jQuery的类数组对象结构

为什么jQuery能像数组一样操作,为什么能通过对象get方法或则直接通过下标0索引就能转化成DOM对象
jQuery的入口统一是$,通过传递参数的不通,实现9种方法的重载,

1. jQuery([selector,[context]])
2. jQuery(element)
3. jQuery(elementArray)
4. jQuery(object)
5. jQuery(jQuery object)
6. jQuery(html,[ownerDocument])
7. jQuery(html,[attributes])
8. jQuery()
9. jQuery(callback)
分为三大块:选择器、dom的处理、dom加载,换句话说,jQuery就是为了获取DOM、操作DOM,
所有,为了更方便这些操作,让节点与实例对象通过一个桥梁给关联起来,jq内部采用一种叫‘类数组对象’的方式作为存储结构,即可以像对象一样处理jq对象,也能像数组一样可以使用push、pop、shift、unshift、sort、map等类数组的方法操作jq对象。

举个栗子 :

var aQuery = function(selector) {
    //强制为对象
	if (!(this instanceof aQuery)) {
		return new aQuery(selector);
	}
	var elem = document.getElementById(/[^#].*/.exec(selector)[0]);
	this.length = 1;
	this[0] = elem;
	this.context = document;
	this.selector = selector;
	this.get = function(num) {
		return this[num];
	}
	return this;
}

 1、强制为对象,第一次执行时,通过instanceof判断原型是否是aQuery,第一次显然不是,并通过new创建一个新的aQuery对象。

 2、正则中的^代表的是以什么开头,[]代表包含的内容,[^]则代表不包含的内容。返回的是除了#之外的内容,因为是数组,所有要使用[0]来获取。

五、jQuery中的ready与load事件

jQuery中三种文档的加载方式 :

1.

$(document).ready(function () {
	// body...
});

2.方式1的简写

$(function () {
	// body...
});

3.

// $(window).load(function () {
// 	// body...

// });   //如果不支持此方法的使用,则需要在window中添加事件监听来实现//如果不支持此方法的使用,则需要在window中添加事件监听来实现

大家在面试的时候,经常被问到一个问题,ready和load哪一个先执行,答案是ready先执行,load后执行。下面看一下DOM文档的加载步骤 :

(1) 解析HTML结构。
(2) 加载外部脚本和样式表文件。
(3) 解析并执行脚本代码。
(4) 构造HTML DOM模型。//ready 、DOMContentLoaded
(5) 加载图片等外部文件。
(6) 页面加载完毕。//load

由上可以看出,两者的区别是资源文件的加载,ready构建基本的DOM结构,一般使用ready,这样网站页面加载速度更快,而load需要加载完图片等资源才去处理框架的加载。

	// jquery文档加载时机
jQuery.ready.promise = function (obj) {
	if(!readyList){
		readyList = jQuery.Deferred();
		//表示页面已经加载完成,直接调用 ready方法
		if (document.readyState === "complete") {
			//将 jQuery.ready压入异步消息队列,设置延迟时间1毫秒(注意,有些浏览器延迟不能小于4毫秒)
			setTimeout(jQuery.ready);
		}else{
			 //监听DOM加载完成
			document.addEventListener("DOMContentLoaded",complete,false);
			//这里是为了确保所有ready执行结束,如果DOMContentLoaded方法执行了,将有一个状态值 isReady被设置为true,因此,
			 //ready方法一旦执行,那么将只执行一次,window.addEventListener中的ready 将被 return 中断
			window.addEventListener("load",complete,false)
		}
	}
	return readyList.promise(obj);
}// jquery文档加载时机
jQuery.ready.promise = function (obj) {
	if(!readyList){
		readyList = jQuery.Deferred();
		//表示页面已经加载完成,直接调用 ready方法
		if (document.readyState === "complete") {
			//将 jQuery.ready压入异步消息队列,设置延迟时间1毫秒(注意,有些浏览器延迟不能小于4毫秒)
			setTimeout(jQuery.ready);
		}else{
			 //监听DOM加载完成
			document.addEventListener("DOMContentLoaded",complete,false);
			//这里是为了确保所有ready执行结束,如果DOMContentLoaded方法执行了,将有一个状态值 isReady被设置为true,因此,
			 //ready方法一旦执行,那么将只执行一次,window.addEventListener中的ready 将被 return 中断
			window.addEventListener("load",complete,false)
		}
	}
	return readyList.promise(obj);
}

六、jQuery多库共存处理

多库共存换句话可以叫‘无冲突处理’,主要由于jQuery采用$作为命名空间,不免会与别的框架或插件产生冲突,jQuery给出一个方案--noConflict函数,此函数将$符号的控制权让给其他的库,而使用jQuery来代替$符号
比如:$('name') 换成jQuery('name')

var _jQuery = window.jQuery,
    _$ = window.$;

jQuery.noConflict = function(){
	if( window.$ === jQuery){
		window.$ = _$;
	}
	if(deep && window.jQuery === jQuery){
		window.jQuery = _jQuery;
	}
	return jQuery;
}	

//上面的函数必须在导入jQuery文件之后,并且需要有相同$作为命名空间的库。
//首先将外部的window.$赋予_$,在noConflict中进行判断,如果没有交出控制权则将window.$与之前保存的_$替换。

本文参考资料为 : http://www.imooc.com/code/3093

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值