jQuery基本结构
(function( window, undefined ) {
var jQuery = function( ) {
return new jQuery.prototype.init( );
}
jQuery.prototype = {
constructor: jQuery
}
jQuery.prototype.init.prototype = jQuery.prototype;
window.jQuery = window.$ = jQuery;
})( window );
-
jQuery本质是一个闭包:防止与其他框架产生冲突
-
jQuery让外界访问内部局部变量方法
window.jQuery = window.$ = jQuery; //将jQuery方法放在window上
-
jQuery window参数的含义和作用
- 为了以后方便压缩代码
- 提高查找效率:在内部就可以查找到window
-
jQuery undefined参数的含义和作用
- 为了以后方便压缩代码
- 旧版本的浏览器(IE9一下)
undefined
可以被赋值,为了保证内部的undefined
不被污染,所以需要正确接收一个undefined
入口函数测试
- 传入 ‘’
null
undefined
NaN
0false
:返回一个空的jQuery对象
console.log($());
console.log($(''));
console.log($(null));
console.log($(undefined));
console.log($(NaN));
console.log($(0));
console.log($(false));
- 传入HTML代码片段 :会将DOM元素创建好并存储到jQuery对象中返回
console.log($('<p>1</p><p>2</p><p>3</p>'));
//创建三个p元素
- 传入选择器 : 将找到的所有元素存储到jQuery对象中返回
console.log($('p'));
- 传入数组 : 将数组中存储的元素依次存储到jQuery对象中返回
let arr = [1, 2, 3, 4, 5, 6];
console.log($(arr));
- 传入伪数组 :将数组中存储的元素依次存储到jQuery对象中返回
let likeArr = {0:"lnj", 1:"33", 2:"male", length: 3};
console.log($(likeArr));
- 传入对象 : 将传入的对象存储到jQuery对象中返回
function Person() {}
console.log($(new Person()));
- 传入DOM元素:将传入的DOM元素存储到jQuery对象中返回
console.log($(document.createElement('div')));
- 传入基本数据类型:将传入的基本数据类型存储到jQuery对象中返回
console.log($(123));
入口函数代码实现
(function (window, undefined) {
let jQuery = function(selector){
return new jQuery.prototype.init(selector)
}
jQuery.prototype = {
constructor : jQuery,
init : function (selector) {
// trim -> 去除字符串两端的空格
selector = jQuery.trim(selector)
//
if(!selector){
return this
}
// 方法处理
else if(jQuery.isFunction(selector)){
jQuery.ready(selector)
}
// 字符串处理
else if(jQuery.isString(selector)){
// 判断是否为代码片段
if(jQuery.isHTML(selector)){
let temp = document.createElement("div");
temp.innerHTML = selector
// this指向的不是数组 是 jQuery对象
[].push.apply(this,temp.children);
}
// 判断传入是个为选择器
else{
// 利用querySelectorAll方法找到对应元素
let res = document.querySelectorAll(selector);
// 将找到的元素添加到jQuery上
[].push(this,res)
}
}
// 判断是否为数组
else if(jQuery.isArray(selector)){
//真数组
// if(({}).toString.apply(selector) === "[object Array]"){
// [].push.apply(this, selector)
// return this;
// }
// 伪数组
// else{
// // 将自定义的伪数组转换为真数组
// let arr = [].slice.call(selector);
// // 将真数组转换为伪数组
// [].push.apply(this, arr);
// return this;
// }
// 统一方法
let arr = [].slice.call(selector);
[].push.apply(this, arr);
}
// 其他类型
else{
this[0] = selector;
this.lenght = 1;
}
// 统一返回
return this;
}
}
jQuery.extend = jQuery.prototype.extend = function (obj) {
for(let key in obj){
this[key] = obj[key]
// this[key] -> 将键名传入给jQuery对象
// obj[key] -> 获取对应键的值
}
}
jQuery.extend({
// 判断传入是否为字符串
isString : function(str){
return typeof str === "string"
},
// 判断传入是否为代码片段
isHTML : function (str) {
return str.charAt(0) == "<" &&
str.charAt(str.length - 1) == ">" &&
str.length >= 3
},
trim : function (str) {
// 如果不是字符串 直接返回
if(!jQuery.isString(str)){
return str
}
// 判断是否支持trim方法
if(str.trim){
return str.trim()
}else{
// 兼容IE方法
return str.replace(/^\s+|\s+$/g, "")
}
},
// 判断传入是否为对象
isObject : function (obj) {
return typeof obj === "object"
},
// 判断传入是否为window
isWindow : function (w) {
return typeof w === window
},
// 数组判断
isArray : function (sele) {
// 是对象 不能是window 必须带有 length属性
if(jQuery.isObject(sele) &&
!jQuery.isWindow(sele) &&
"length" in sele) {
return true;
}
return false
},
// 判断是否为函数
isFunction : function (sele) {
return typeof sele === "function";
},
ready : function (fn) {
// 判断DOM是否加载完毕
if(document.readyState === "complete"){
fn()
}else if(document.addEventListener){
// 判断是否支持 addEventListener方法
document.addEventListener("DOMContentLoaded", function () {
fn();
});
}else{
document.attachEvent("onreadystatechange", function () {
if(document.readyState == "complete"){
fn();
}
});
}
}
});
jQuery.prototype.init.prototype = jQuery.prototype;
window.jQuery = window.$ = jQuery;
})(window)