jquery源码分析(一) —— 理解架构
part_one 便捷的操作
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>便捷的操作</title> 6 <style> 7 p { color:red; margin:5px; cursor:pointer; } 8 p:hover { background:yellow; } 9 10 .selected { color:blue; } 11 .highlight { background:yellow; } 12 13 div { 14 background-color:#bca; 15 width:220px; 16 border:1px solid green; 17 } 18 div { color:red; } 19 </style> 20 </head> 21 <body> 22 <!-- 例一 --> 23 <p>First Paragraph</p> 24 <p>Second Paragraph</p> 25 <p>Yet one more Paragraph</p> 26 27 <hr> 28 29 <!-- 例二 --> 30 <button id="go">» Run</button> 31 <div id="block">Hello!</div> 32 33 <hr> 34 35 <!-- 例三 --> 36 <form> 37 <input type="checkbox" name="newsletter" value="Hourly" checked="checked"> 38 <input type="checkbox" name="newsletter" value="Daily"> 39 <input type="checkbox" name="newsletter" value="Weekly"> 40 <input type="checkbox" name="newsletter" value="Monthly" checked> 41 <input type="checkbox" name="newsletter" value="Yearly"> 42 </form> 43 <div id="t"></div> 44 45 46 <script src="../../jq/jquery-2.1.1.min.js"></script> 47 <script> 48 $(document).ready(function() { 49 // 例一 50 $("p").click(function() { 51 $(this).slideUp(); 52 }); 53 54 // 例二 55 $("#go").click(function() { 56 $("#block").animate({ 57 width: "70%", 58 opacity: 0.5, 59 marginLeft: "0.6in", 60 fontSize: "3em", 61 borderWidth: "10px" 62 }, 1500); 63 }); 64 65 // 例三 66 var countChecked = function() { 67 var n = $("input:checked").length; 68 if (n < 1) { 69 $("#t").text("no checked!"); 70 return; 71 } 72 $("#t").text(n + (n === 1 ? " is" : " are") + " checked!"); 73 } 74 75 $("input[type=checkbox]").on("click", countChecked); 76 77 }); 78 </script> 79 </body> 80 </html>
part_two 整体架构
<script type="text/javascript"> ;(function(global, factory) { factory(global); }(typeof window !== "undefined" ? window : this, function(window, noGlobal) { var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }; jQuery.fn = jQuery.prototype = {}; // 核心方法 // 回调系统 // 异步队列 // 数据缓存 // 队列操作 // 选择器引 // 属性操作 // 节点遍历 // 文档处理 // 样式操作 // 属性操作 // 事件体系 // AJAX交互 // 动画引擎 return jQuery; })); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } return jQuery.ajax({ url: url, type: method, dataType: type, data: data, success: callback }); }; }); </script>
part_three 自调用表达式(三种)
问:JavaScript中(function(){…})(); 与 (function(){…}()); 这两种写法在意义上有什么区别?
答:这个问题可以从不同的角度来看,但从结果上来说,个人的意见是:他们是一样的。
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>jQuery中三种立即调用函数表达式写法</title> 6 </head> 7 <body> 8 9 <p>总之记住: 10 <ol> 11 <li> 12 <pre> 13 ;(function(window, ff) { 14 ff('say hello') 15 }(window, function(str) { 16 alert(str); 17 })) 18 </pre> 19 </li> 20 <li> 21 <pre> 22 (function(window, ff) { 23 ff('say hello') 24 })(window, function(str) { 25 alert(str); 26 }); 27 </pre> 28 </li> 29 </ol> 30 是一样一样的。 31 </p> 32 33 <hr> 34 35 <p>jQuery的[立即调用函数表达式]的写法有三种</p> 36 <p> 37 在知乎上看到的这个问题<br> 38 <b>JavaScript中(function(){…})(); 与 (function(){…}()); 这两种写法在意义上有什么区别?</b><br> 39 的回答的第一句↓,突然就有一种幡然醒悟的感觉了。<br> 40 <b>这个问题可以从不同的角度来看,但从结果上来说,个人的意见是:他们是一样的。</b><br> 41 <a title="去这儿" href="http://www.zhihu.com/question/20292224" target="_blank">http://www.zhihu.com/question/20292224</a> 42 </p> 43 44 45 <script> 46 47 // 代码中嵌套了2个函数,而且把一个函数作为参数传递到另一个函数中并且执行 48 ;(function(window, factory) { 49 var aName = factory(); // 调用factory()函数返回的还是一个函数,要比较一下与下面的一个的不同 50 //aName(); // 调用aName()函数 51 }(this, function() { 52 return function() { 53 alert('jQuery的调用详情......'); 54 } 55 })) 56 57 // 为了安全起见最好在前面加上这个";",避免如果之前是不是以";"结尾的话,会报错 —— Uncaught TypeError: undefined is not a function 58 ;(function(window, factory) { 59 //factory('终于成功了'); // 调用factory函数,并赋予'终于成功了'这个字符串参数 60 }(window, function(para) { 61 alert(para); 62 })) 63 64 /* 65 66 var undefined = '慕课网' 67 ;(function(window) { 68 alert(undefined);//只有是IE8 '慕课网' 69 })(window) 70 71 ;(function() { 72 alert('you are in 1......'); 73 })() 74 75 ;(function() { 76 alert('you are in 2......'); 77 })() 78 79 */ 80 81 // 可以简化为↓ 82 83 var factory = function() { 84 return function() { 85 // 执行方法 86 alert('调用详情......'); 87 } 88 } 89 var jQuery = factory(); // jQuery是factory函数执行后返回的函数 90 //jQuery(); // 调用jQuery这个函数 91 92 93 // 写法三: 94 (function(window, undefined) { 95 //alert('undefined ==> ' + undefined); 96 var jQuery123 = function() { 97 alert('jQuery123这个函数的相关内部调用......'); 98 } 99 window.jQuery = window.$ = jQuery123; 100 //window.$(); // 调用jQuery123这个函数 101 })(window, '张宝'); 102 //alert($()); // 外部调用 103 104 105 106 //function isFunction(fn) { 107 // if (typeof fn == 'function') { 108 // return '是函数'; 109 // } 110 // return '不是函数'; 111 //} 112 // 用()将匿名函数括起来 —— (function(){})) 113 //alert(isFunction((function(){}))); // 是函数 114 // 加上 (); 就实现了普通函数的调用了 115 //(function() { var i = j = 3; alert((i+j)); })(); 116 117 118 </script> 119 </body> 120 </html>
part_four jQuery的对象结构
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>jQuery类数组对象结构</title> 6 <style> 7 div{ 8 width: 30px; 9 height: 10px; 10 float:left; 11 } 12 </style> 13 </head> 14 <body> 15 16 <p>类数组对象:jQuery对象可用数组下标索引</p> 17 <p>通过对象键值对的关系保存着属性,原型保存着方法</p> 18 19 <hr> 20 21 <button id="test1">jQuey[0]</button> 22 <button id="test2">jQuey.get</button> 23 <button id="test3">aQuery[0]</button> 24 <button id="test4">aQuery.get</button> 25 26 <p id="book">book</p> 27 28 <div id="show1"></div><br> 29 <div id="show2"></div><br> 30 <div id="show3"></div><br> 31 <div id="show4"></div><br> 32 33 <script src="../../jq/jquery-2.1.1.min.js"></script> 34 <script> 35 // 以下是模拟jQuery的对象结构 36 var aQuery = function(selector) { 37 // 强制为对象 38 if (!(this instanceof aQuery)) { 39 return new aQuery(selector); 40 } 41 var elem = document.getElementById(/[^#].*/.exec(selector)[0]); 42 this.lenght = 1; 43 this[0] = elem; 44 this.context = document; 45 this.selector = selector; 46 this.get = function(num) { 47 return this[num]; 48 }; 49 return this; 50 }; 51 console.log((new aQuery('#book'))); 52 53 $("#test1").click(function() { 54 $('#show1').append($('#book')[0]); 55 }); 56 57 $("#test2").click(function() { 58 $('#show2').append($('#book').get(0)); 59 }); 60 61 $("#test3").click(function() { 62 $('#show3').append(aQuery("#book")[0]); 63 }); 64 65 $("#test4").click(function() { 66 $('#show4').append(aQuery("#book").get(0)); 67 }) 68 69 70 //console.log($('#test1')); 71 //alert($('#test1')['0'].outerHTML); 72 //alert($('#test1')[0].outerHTML); 73 //alert($('#test1').get('context')); 74 </script> 75 </body> 76 </html>
part_five 脚本加载顺序
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>dom加载</title> 6 </head> 7 <body> 8 9 <script src="../../jq/jquery-2.1.1.min.js"></script> 10 <script> 11 12 show('观察脚本的加载顺序'); 13 14 document.addEventListener("DOMContentLoaded", function() { 15 show('DOMContentLoaded回调'); 16 }, false); 17 18 window.addEventListener("load", function() { 19 show('load事件回调'); 20 }, false); 21 22 show('脚本解析一'); 23 24 // 测试加载 25 $(function() { 26 show('脚本解析二'); 27 }); 28 29 show('脚本解析三'); 30 31 32 function show(data) { 33 if (!data) { 34 return $("body").append('</br>') 35 } 36 if (typeof data === 'object') { 37 for (var key in data) { 38 $("body").append('<li>key->' + key + '; value->'+ data[key] +'</li>') 39 } 40 } else { 41 $("body").append('<li>' + data + '</li>') 42 } 43 } 44 </script> 45 </body> 46 </html>
上面的代码输出效果:
观察脚本的加载顺序
脚本解析一
脚本解析三
脚本解析二
DOMContentLoaded回调
load事件回调
part_six jquery多库共存方法noConflict
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>title</title> </head> <body> <div id="fzb">测试noConflict效果</div> <script src="../../jq/jquery-2.1.1.min.js"></script> <script> $("#fzb").click(function() { $.noConflict(); //让出控制权 if (!$) { show("使用noConflict后,$不存在") } if (jQuery) { show("使用noConflict后,jQuery存在") } //通过闭包隔离出$ ;(function($) { if ($) { show("通过闭包隔离后,转为局部变量$存在") } })(jQuery); }) function show(data) { jQuery("body").append('<li>' + data + '</li>') } </script> </body> </html>
浙公网安备 33010602011771号