jQuery学习-day05
jq的基本结构
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <script type="text/javascript" src="../js/jquery-1.12.4.js"></script> 6 7 <script type="text/javascript"> 8 /* 9 1.JQ的本质是一个闭包 10 2.JQ为什么要用闭包来实现? 11 为了避免多个框架的冲突 12 3.JQ如何让外界访问内部定义的局部变量 13 window.xxx = xxx; 14 4.JQ为什么要给自己传递一个window参数 15 为了方便后期压缩代码 16 为了提升查找的效率 17 5.JQ为什么要给自己接收一个undefinde 18 为了方便后期压缩代码 19 -IE9以下的浏览器undefined可以被修改,所以需要接收一个正确的undefined 20 21 */ 22 23 //JQ方法 24 (function (window,undefined){ 25 var jQuery = function(){ 26 return new jQuery.prototype.init(); 27 } 28 29 jQuery.prototype = { 30 constructor : jQuery; 31 } 32 33 jQuery.prototype.init.prototype = jQuery.prototype; 34 //变成了全局变量 35 window.jQuery = window.$ =jQuery; 36 })(window); 37 38 //原生JS 39 (function f1(){ 40 var num = 10; 41 //将局部变量变成全局变量 42 window.num = num; 43 })();//引用该函数 44 45 (function f2(){ 46 var num = 20; 47 })(); 48 console.log(num);//10 49 </script> 50 </head> 51 <body> 52 53 </body> 54 </html>
自定义的JQ基本结构
1 (function (window,undefined){ 2 var ajQuery = function(){ 3 return new ajQuery.prototype.init(); 4 } 5 6 ajQuery.prototype = { 7 constructor : ajQuery; 8 } 9 10 ajQuery.prototype.init.prototype = ajQuery.prototype; 11 //变成了全局变量 12 window.ajQuery = window.$ = ajQuery; 13 })(window);
JQ入口函数测试
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <script type="text/javascript" src="../js/jquery-1.12.4.js"></script> 6 <script type="text/javascript"> 7 /* 8 jq入口函数传入不同参数得到的实例 9 1.传入‘’ null undefined NaN 0 false 10 2.传入html片段 11 3.传入选择器 12 4.传入数组 13 5.传入伪数组 14 6.传入对象 15 7.传入DOM元素 16 8.传入基本数据类型 17 */ 18 19 //1.传入‘’ null undefined NaN 0 false 20 //会返回一个空的JQ对象,而且都是一样的 21 // console.log($()); 22 // console.log($('')); 23 // console.log($(null)); 24 // console.log($(undefined)); 25 // console.log($(NaN)); 26 // console.log($(0)); 27 // console.log($(false)); 28 29 //2.传入html片段 30 //先传入DOM元素,会将创建好的DOM元素存储到JQ对象中返回,控制台会看到两个p标签 31 console.log($('<p>11</p><p>22</p>')); 32 33 //3.传入选择器 34 //会将找到的所有元素存储到JQ对象中返回 35 console.log($('li')); 36 37 // 4.传入数组 38 //会将数组中的元素依次存储到JQ对象中返回 39 console.log($([1,2,3,4,5,6])); 40 41 // 5.传入伪数组 42 //会将数组中的元素依次存储到JQ对象中返回 43 var likeArr = {0:"coco",1:"jelly",length:2}; 44 console.log(likeArr); 45 46 // 6.传入对象 47 //会将传入的对象存储到JQ对象中返回 48 function Person(){} 49 console.log($(new Person())); 50 51 // 7.传入DOM元素 52 //会将传入的对象存储到JQ对象中返回 53 console.log($(document.createElement('div'))); 54 55 // 8.传入基本数据类型 56 //会将传入的数据类型存储到JQ对象中返回 57 console.log($(123)); 58 console.log($(true)); 59 60 /* 61 1.传入 '' null undefined NaN 0 false, 返回空的jQuery对象 62 2.字符串: 63 代码片段:会将创建好的DOM元素存储到jQuery对象中返回 64 选择器: 会将找到的所有元素存储到jQuery对象中返回 65 3.数组: 66 会将数组中存储的元素依次存储到jQuery对象中立返回 67 4.除上述类型以外的: 68 会将传入的数据存储到jQuery对象中返回 69 */ 70 71 </script> 72 </head> 73 <body> 74 <ul> 75 <li>ul中的li</li> 76 </ul> 77 </body> 78 </html>
apply和call的区别 https://www.jianshu.com/p/80ea0d1c04f8
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <meta charset="utf-8"> 6 </head> 7 <script type="text/javascript"> 8 /* 9 格式 10 call(对象,参数1,参数2,...) 11 apply(对象,[数组]) 12 13 */ 14 15 function test(){ 16 console.log(this); 17 } 18 window.test(); 19 20 var obj = {"name":"coco"}; 21 22 /* 23 1.通过window.test找到test方法 24 2.通过apply(obj)将找到的test方法内部的this修改为自定义的对象 25 */ 26 window.test.apply(obj); 27 window.test.call(obj); 28 29 30 /* 31 1.通过window.sum找到sum方法 32 2.通过apply(obj)将找到的sum方法内部的this修改为自定义的对象 33 3.将传入数组中的元素依次取出,传递给形参 34 */ 35 function sum(a,b){ 36 console.log(this); 37 console.log(a+b); 38 } 39 //传递参数的形式有区别,call就是一个一个的对象依次传入,而apply就是用数组传入 40 //call()会再输出一次函数内部的this,而apply不会 41 window.sum.call(obj,1,2); 42 window.sum.apply(obj,[3,5]); 43 44 45 //新建了一个数组,用push方法添加元素 46 var arr = []; 47 arr.push(1); 48 console.log(arr); 49 50 51 //真数组转换为伪数组的一个过程 52 var arr1 = [1,2,3,4,5]; 53 var obj = {}; 54 /* 55 1.通过[].push找到数组中的push方法 56 2.通过apply(obj)将找到push方法内部的this修改为自定义的对象 57 3.将传入数组中的元素依次取出,传递给形参 58 */ 59 [].push.apply(obj,arr1); 60 console.log(obj); 61 window.onload = function(ev){ 62 //系统自带的伪数组 63 var res = document.querySelectorAll("div"); 64 //自定义的伪数组 65 var res1 = {0:"coco",1:"jelly",length:2}; 66 //真数组 67 var arr2 = [1,2,3]; 68 69 [].push.apply(arr2,res1); 70 console.log("arr2:"+arr2);//arr2:1,2,3,coco,jelly 71 72 //如果想将伪数组转换为真数组。可以用如下方法 73 var arr3 = [2,4,6,8,10]; 74 //如果slice方法声明参数都没有传递,会将数组中的元素放到一个新的数组中原样返回 75 var sli = arr3.slice(); 76 var sli2 = arr3.slice(2); 77 var sli3 = arr3.slice(2,4); 78 console.log(sli+"<br>"+sli2+"<br>"+sli3); 79 // 2,4,6,8,10<br>6,8,10<br>6,8 80 } 81 </script> 82 83 84 <body> 85 86 </body> 87 </html>
可以自己编辑的JQ原理(老师的)
1 (function( window, undefined ) { 2 var njQuery = function(selector) { 3 return new njQuery.prototype.init(selector); 4 } 5 njQuery.prototype = { 6 constructor: njQuery, 7 init: function (selector) { 8 /* 9 1.传入 '' null undefined NaN 0 false, 返回空的jQuery对象 10 2.字符串: 11 代码片段:会将创建好的DOM元素存储到jQuery对象中返回 12 选择器: 会将找到的所有元素存储到jQuery对象中返回 13 3.数组: 14 会将数组中存储的元素依次存储到jQuery对象中立返回 15 4.除上述类型以外的: 16 会将传入的数据存储到jQuery对象中返回 17 */ 18 // 0.去除字符串两端的空格 19 selector = njQuery.trim(selector); 20 21 // 1.传入 '' null undefined NaN 0 false, 返回空的jQuery对象 22 if(!selector){ 23 return this; 24 } 25 // 2.方法处理 26 else if(njQuery.isFunction(selector)){ 27 njQuery.ready(selector); 28 } 29 // 3.字符串 30 else if(njQuery.isString(selector)){ 31 // 2.1判断是否是代码片段 <a> 32 if(njQuery.isHTML(selector)){ 33 // 1.根据代码片段创建所有的元素 34 var temp = document.createElement("div"); 35 temp.innerHTML = selector; 36 /* 37 // 2.将创建好的一级元素添加到jQuery当中 38 for(var i = 0; i < temp.children.length; i++){ 39 this[i] = temp.children[i]; 40 } 41 // 3.给jQuery对象添加length属性 42 this.length = temp.children.length; 43 */ 44 [].push.apply(this, temp.children); 45 // 此时此刻的this是njQuery对象 46 // 4.返回加工好的this(jQuery) 47 // return this; 48 } 49 // 2.2判断是否是选择器 50 else{ 51 // 1.根据传入的选择器找到对应的元素 52 var res = document.querySelectorAll(selector); 53 // 2.将找到的元素添加到njQuery上 54 [].push.apply(this, res); 55 // 3.返回加工上的this 56 // return this; 57 } 58 } 59 // 4.数组 60 // else if(typeof selector === "object" && 61 // "length" in selector && 62 // selector !== window){ 63 else if(njQuery.isArray(selector)){ 64 /* 65 // 3.1真数组 66 if(({}).toString.apply(selector) === "[object Array]"){ 67 [].push.apply(this, selector); 68 return this; 69 } 70 // 3.2伪数组 71 else { 72 // 将自定义的伪数组转换为真数组 73 var arr = [].slice.call(selector); 74 // 将真数组转换为伪数组 75 [].push.apply(this, arr); 76 return this; 77 } 78 */ 79 // 将自定义的伪数组转换为真数组 80 var arr = [].slice.call(selector); 81 // 将真数组转换为伪数组 82 [].push.apply(this, arr); 83 // return this; 84 } 85 // 5.除上述类型以外 86 else{ 87 this[0] = selector; 88 this.length = 1; 89 // return this; 90 } 91 return this; 92 } 93 } 94 njQuery.extend = njQuery.prototype.extend = function (obj) { 95 for(var key in obj){ 96 this[key] = obj[key]; 97 } 98 } 99 njQuery.extend({ 100 isString : function(str){ 101 return typeof str === "string" 102 }, 103 isHTML : function(str){ 104 return str.charAt(0) == "<" && 105 str.charAt(str.length - 1) == ">" && 106 str.length >= 3 107 }, 108 trim : function(str){ 109 if(!njQuery.isString(str)){ 110 return str; 111 } 112 // 判断是否支持trim方法 113 if(str.trim){ 114 return str.trim(); 115 }else{ 116 return str.replace(/^\s+|\s+$/g, ""); 117 } 118 }, 119 isObject : function(sele){ 120 return typeof sele === "object" 121 }, 122 isWindow : function(sele){ 123 return sele === window; 124 }, 125 isArray : function(sele){ 126 if(njQuery.isObject(sele) && 127 !njQuery.isWindow(sele) && 128 "length" in sele){ 129 return true; 130 } 131 return false; 132 }, 133 isFunction : function(sele){ 134 return typeof sele === "function"; 135 }, 136 ready: function (fn) { 137 // 判断DOM是否加载完毕 138 if(document.readyState == "complete"){ 139 fn(); 140 }else if(document.addEventListener){ 141 document.addEventListener("DOMContentLoaded", function () { 142 fn(); 143 }); 144 }else{ 145 document.attachEvent("onreadystatechange", function () { 146 if(document.readyState == "complete"){ 147 fn(); 148 } 149 }); 150 } 151 } 152 }); 153 154 njQuery.prototype.init.prototype = njQuery.prototype; 155 window.njQuery = window.$ = njQuery; 156 })( window );