脚本宝典收集整理的这篇文章主要介绍了

jquery源码学习 (一) 概况

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。
<p><code></p> <h4><a href="http://www.js-code.com/tag/jquery" title="jQuery" target="_blank">jQuery</a></h4> <blockquote><p> <code><a href="http://www.js-code.com/tag/jquery" title="jQuery" target="_blank">jQuery</a></code>是继<code>prototype</code>之后又一个优秀的Javascript框架。它是轻量级的js库 ,它<code>兼容<a href="http://www.js-code.com/tag/css" title="CSS" target="_blank">CSS</a>3</code>,还<code>兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+)</code>,<strong><code><a href="http://www.js-code.com/tag/jquery" title="浏览关于“jQuery”的文章" target="_blank" class="tag_link">jQuery</a>2.0</code>及后续版本将不再支持<code>IE6/7/8</code>浏览器</strong>。jQuery使用户能更方便地处理<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>(标准通用标记语言下的一个应用)、events、实现动画效果,并且方便地为网站提供<code><a href="http://www.js-code.com/tag/ajax" title="AJAX" target="_blank">AJAX</a>交互</code>。jQuery还有一个比较大的优势是,它的文档说明很全,而且各种应用也说得很详细,同时还有许多成熟的插件可供选择。jQuery能够使用户的html页面保持代码和html内容分离,也就是说,不用再在html里面插入一堆js来调用命令了,只需定义id即可。</p> <p>jquery大致可以分为 <a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a> 、 ajax 、选择器 、 事件 、 动画。当然jquery有13个模块之多,这里的5个,是从另外一个角度划分的。</p> </blockquote> <p>(令: jquery从2.0之后就不兼容IE 6/7/8 了)</p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015214075" src="https://cdn.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <blockquote><p>一、 总体架构</p></blockquote> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=";(function(global, factory) { // 传入window可以将其作为一个局部变量使用,缩短了作用域链,大大加快执行速度 factory(global); }(typeof window !== &quot;undefined&quot; ? window : this, function(window, noGlobal) { // jquery方法 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }; // jQuery.fn 是 jquery对象的原型对象 jQuery.fn = jQuery.prototype = {}; // 核心方法 // 回调系统 // 异步队列 // 数据缓存 // 队列操作 // 选择器引 // 属性操作 // 节点遍历 // 文档处理 // 样式操作 // 属性操作 // 事件体系 // AJAX交互 // 动画引擎 if ( typeof noGlobal === strundefined ) { window.jQuery = window.$ = jQuery; } return jQuery; })); " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript">;(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">global, factory</span>) </span>{ <span class="hljs-comment">// 传入window可以将其作为一个局部变量使用,缩短了作用域链,大大加快执行速度</span> factory(global); }(<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span> !== <span class="hljs-string">"undefined"</span> ? <span class="hljs-built_in">window</span> : <span class="hljs-keyword"><a href="http://www.js-code.com/tag/this" title="浏览关于“this”的文章" target="_blank" class="tag_link">this</a></span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">window, noGlobal</span>) </span>{ <span class="hljs-comment">// jquery方法</span> <span class="hljs-keyword">var</span> jQuery = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> selector, context </span>) </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> jQuery.fn.init( selector, context ); }; <span class="hljs-comment">// jQuery.fn 是 jquery对象的原型对象</span> jQuery.fn = jQuery.prototype = {}; <span class="hljs-comment">// 核心方法</span> <span class="hljs-comment">// 回调系统</span> <span class="hljs-comment">// 异步队列</span> <span class="hljs-comment">// 数据缓存</span> <span class="hljs-comment">// 队列操作</span> <span class="hljs-comment">// 选择器引</span> <span class="hljs-comment">// 属性操作</span> <span class="hljs-comment">// 节点遍历</span> <span class="hljs-comment">// 文档处理</span> <span class="hljs-comment">// 样式操作</span> <span class="hljs-comment">// 属性操作</span> <span class="hljs-comment">// 事件体系</span> <span class="hljs-comment">// <a href="http://www.js-code.com/tag/ajax" title="浏览关于“AJAX”的文章" target="_blank" class="tag_link">AJAX</a>交互</span> <span class="hljs-comment">// 动画引擎</span> <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> noGlobal === strundefined ) { <span class="hljs-built_in">window</span>.jQuery = <span class="hljs-built_in">window</span>.$ = jQuery; } <span class="hljs-keyword">return</span> jQuery; })); </code></pre> <p>关于上述代码,解释如下:</p> <ol> <li>jQuery的整体代码包裹在一个立即执行的自调用匿名的函数中,这样可以尽量减少和其他第三方库的干扰;自动初始化这个函数,让其只构建一次。</li> <li>在上述代码最后,将jQuery对象添加到全局window上,并为之设置变量$,从而使得可以在外界访问jQuery;</li> <li>为自调用匿名函数设置参数global,并传入参数window,这样一方面可以缩短作用域链,可以尽快访问到window;</li> </ol> <ul> <li>自调用函数的原理(立即执行的自调用函数)</li> </ul> <blockquote><p>jQuery使用()将匿名函数括起来,然后后面再加一对小括号(包含参数列表)的目的,简单来说就是小括号括起来后,就当作是一个表达式来处理,得到的就是一个 <code>function </code>对象了。同时小括号也取得了这个函数的引用位置,然后传入参数就可以直接执行了。</p></blockquote> <blockquote><p>总结: 全局变量是魔鬼, 匿名函数可以有效的保证在页面上写入JavaScript,而不会造成全局变量的污染,通过小括号,让其加载的时候立即初始化,这样就形成了一个单例模式的效果从而只会执行一次。</p></blockquote> <hr> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="(function( global, factory ) { // 因为jquery既要再普通环境下运行,也要再例如AMD、commonJs下运行,所以我们需要做不同的适应 // node CommonJs规范 if ( typeof module === &quot;object&quot; &amp;&amp; typeof module.exports === &quot;object&quot; ) { module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( &quot;jQuery requires a window with a document&quot; ); } return factory( w ); }; } else { // AMD factory( global ); } // 传入参数(window和一个执行函数) }(typeof window !== &quot;undefined&quot; ? window : this, function( window, noGlobal ) { // 【1】 // 创建jQuery对象, 实际上是jQuery.fn.init所返回的对象 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); // 如果调用new jQuery, 生成的jQuery会被丢弃,最后返回jQuery.fn.init对象 // 因此可以直接调用jQuery(selector, context), 不需要使用new // 如果使用new jQuery()容易出现死循环 // 我们平常使用 $() ,就是直接调用jquery函数了 } // 【2】 // 创建jQuery对象原型,为jQuery添加各种方法 jQuery.fn = jQuery.prototype = { ... } // 【3】 // 在调用new jQuery.fn.init后, jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype // 相当于将所有jQuery.fn的方法都挂载到一开始jQuery函数返回的对象上 // 这里就是jquery的一个独特之处了,非常的巧妙 jQuery.fn.init.prototype = jQuery.fn; // 【4】 // 创建jQuery.extend方法 jQuery.extend = jQuery.fn.extend = function() {、 ... } // 【5】 // 使用jQuery.extend扩展静态方法 jQuery.extend({}); // 【6】 // 为window全局变量添加$对象,在给window全局添加变量的时候很有可可能会导致变量命名冲突哦,我们之后会学习到如何处理这种命名冲突的解决方法 if ( typeof noGlobal === strundefined ) { // var strundefined = typeof undefined window.jQuery = window.$ = jQuery; // $('') // 同 jQuery('') } return jQuery; })); " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript">(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> global, factory </span>) </span>{ <span class="hljs-comment">// 因为jquery既要再普通环境下运行,也要再例如AMD、commonJs下运行,所以我们需要做不同的适应</span> <span class="hljs-comment">// <a href="http://www.js-code.com/tag/node" title="浏览关于“node”的文章" target="_blank" class="tag_link">node</a> CommonJs规范</span> <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span> === <span class="hljs-string">"object"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span>.<a href="http://www.js-code.com/tag/export" title="浏览关于“export”的文章" target="_blank" class="tag_link">export</a>s === <span class="hljs-string">"object"</span> ) { <span class="hljs-built_in">module</span>.exports = global.document ? factory( global, <span class="hljs-literal">true</span> ) : <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> w </span>) </span>{ <span class="hljs-keyword">if</span> ( !w.document ) { <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>( <span class="hljs-string">"jQuery requires a window with a document"</span> ); } <span class="hljs-keyword">return</span> factory( w ); }; } <span class="hljs-keyword">else</span> { <span class="hljs-comment">// AMD</span> factory( global ); } <span class="hljs-comment">// 传入参数(window和一个执行函数) </span> }(<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span> !== <span class="hljs-string">"undefined"</span> ? <span class="hljs-built_in">window</span> : <span class="hljs-keyword">this</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> window, noGlobal </span>) </span>{ <span class="hljs-comment">// 【1】</span> <span class="hljs-comment">// 创建jQuery对象, 实际上是jQuery.fn.init所返回的对象</span> <span class="hljs-keyword">var</span> jQuery = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> selector, context </span>) </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> jQuery.fn.init( selector, context ); <span class="hljs-comment">// 如果调用new jQuery, 生成的jQuery会被丢弃,最后返回jQuery.fn.init对象</span> <span class="hljs-comment">// 因此可以直接调用jQuery(selector, context), 不需要使用new</span> <span class="hljs-comment">// 如果使用new jQuery()容易出现死循环</span> <span class="hljs-comment">// 我们平常使用 $() ,就是直接调用jquery函数了</span> } <span class="hljs-comment">// 【2】</span> <span class="hljs-comment">// 创建jQuery对象原型,为jQuery添加各种方法</span> jQuery.fn = jQuery.prototype = { ... } <span class="hljs-comment">// 【3】</span> <span class="hljs-comment">// 在调用new jQuery.fn.init后, jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype</span> <span class="hljs-comment">// 相当于将所有jQuery.fn的方法都挂载到一开始jQuery函数返回的对象上</span> <span class="hljs-comment">// 这里就是jquery的一个独特之处了,非常的巧妙</span> jQuery.fn.init.prototype = jQuery.fn; <span class="hljs-comment">// 【4】</span> <span class="hljs-comment">// 创建jQuery.extend方法</span> jQuery.extend = jQuery.fn.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{、 ... } <span class="hljs-comment">// 【5】</span> <span class="hljs-comment">// 使用jQuery.extend扩展静态方法</span> jQuery.extend({}); <span class="hljs-comment">// 【6】</span> <span class="hljs-comment">// 为window全局变量添加$对象,在给window全局添加变量的时候很有可可能会导致变量命名冲突哦,我们之后会学习到如何处理这种命名冲突的解决方法</span> <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> noGlobal === strundefined ) { <span class="hljs-comment">// var strundefined = typeof undefined</span> <span class="hljs-built_in">window</span>.jQuery = <span class="hljs-built_in">window</span>.$ = jQuery; <span class="hljs-comment">// $('')</span> <span class="hljs-comment">// 同 jQuery('')</span> } <span class="hljs-keyword">return</span> jQuery; })); </code></pre> <blockquote><p>二、 jQuery的类<a href="http://www.js-code.com/tag/%e6%95%b0%e7%bb%84" title="数组" target="_blank">数组</a>对象</p></blockquote> <p>可以这么理解,jquery主要的任务就是<code>获取<a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a></code>。<code>操作<a href="http://www.js-code.com/tag/dom" title="浏览关于“DOM”的文章" target="_blank" class="tag_link">DOM</a></code>。</p> <p><code>jQuery</code>的入口都是通过<code>$()</code>来的,通过传入不同的参数,实现了9种重载方法。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="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) // 9种用法整体来说可以分三大块:选择器、dom的处理、dom加载。" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-number">1.</span> jQuery([selector,[context]]) <span class="hljs-number">2.</span> jQuery(element) <span class="hljs-number">3.</span> jQuery(element<a href="http://www.js-code.com/tag/array" title="浏览关于“Array”的文章" target="_blank" class="tag_link">Array</a>) <span class="hljs-number">4.</span> jQuery(object) <span class="hljs-number">5.</span> jQuery(jQuery object) <span class="hljs-number">6.</span> jQuery(html,[ownerDocument]) <span class="hljs-number">7.</span> jQuery(html,[attributes]) <span class="hljs-number">8.</span> jQuery() <span class="hljs-number">9.</span> jQuery(callback) <span class="hljs-comment">// 9种用法整体来说可以分三大块:选择器、dom的处理、dom加载。</span></code></pre> <ul> <li>在jquery内部使用了一种类<a href="http://www.js-code.com/tag/%e6%95%b0%e7%bb%84" title="数组" target="_blank">数组</a>对象的形式,这也是为什么我们获取到同一个class的许多DOM后,既能够调用jquery的方法,又能通过<a href="http://www.js-code.com/tag/%e6%95%b0%e7%bb%84" title="浏览关于“数组”的文章" target="_blank" class="tag_link">数组</a>的方式来处理每一个dom对象了(比如遍历)。</li> </ul> <p><strong>例子喽</strong></p> <p>通过$(".<a href="http://www.js-code.com/tag/class" title="Class" target="_blank">Class</a>")构建的对象结构如下所示:</p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015214076?w=505&amp;h=236" src="https://cdn.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" <div> <span class=&quot;span&quot;>1</span><br /> <span class=&quot;span&quot;>2</span><br /> <span class=&quot;span&quot;>3</span> </div> <p>console.log($('.span'));</p> <p>// jQuery.fn.init(3) [span.span, span.span, span.span, prevObject: jQuery.fn.init(1), context: document, selector: &quot;.span&quot;]<br /> // 0:span.span<br /> // 1:span.span<br /> // 2:span.span<br /> // context: document<br /> // length: 3<br /> // prevObject: jQuery.fn.init [document, context: document]<br /> // selector:&quot;.span&quot;<br /> // __proto__:Object(0)<br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript">&lt;<a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a>&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"span"</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"span"</span>&gt;<span class="hljs-number">2</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class="span"&gt;3&lt;/</span>span&gt; <span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> <span class="hljs-built_in">console</span>.log($(<span class="hljs-string">'.span'</span>)); <span class="hljs-comment">// jQuery.fn.init(3) [span.span, span.span, span.span, prevObject: jQuery.fn.init(1), context: document, selector: ".span"]</span> <span class="hljs-comment">// 0:span.span</span> <span class="hljs-comment">// 1:span.span</span> <span class="hljs-comment">// 2:span.span</span> <span class="hljs-comment">// context: document</span> <span class="hljs-comment">// length: 3</span> <span class="hljs-comment">// prevObject: jQuery.fn.init [document, context: document]</span> <span class="hljs-comment">// selector:".span"</span> <span class="hljs-comment">// __proto__:Object(0)</span> </code></pre> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 模拟一下 function Ajquery(selecter) { // 如果传入的不是一个对象,则将其转换为对象 if(!(selecter instanceof Ajquery)) { return new Ajquery(selecter); } var elem = document.getElementById(/[^#].*/.exec(selector)[0]); // 获取id this[0] = elem; this.length = 1; this.context = document; this.selector = selector; this.get = function(num) { return this[num]; } return this; } // 使用 $('#show2').append(Ajquery('#book').get(0)); // 因此 $('')获取到的就是一个类数组对象" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-comment">// 模拟一下</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Ajquery</span>(<span class="hljs-params">selecter</span>) </span>{ <span class="hljs-comment">// 如果传入的不是一个对象,则将其转换为对象</span> <span class="hljs-keyword">if</span>(!(selecter <span class="hljs-keyword">instanceof</span> Ajquery)) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Ajquery(selecter); } <span class="hljs-keyword">var</span> elem = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-regexp">/[^#].*/</span>.exec(selector)[<span class="hljs-number">0</span>]); <span class="hljs-comment">// 获取id</span> <span class="hljs-keyword">this</span>[<span class="hljs-number">0</span>] = elem; <span class="hljs-keyword">this</span>.length = <span class="hljs-number">1</span>; <span class="hljs-keyword">this</span>.context = <span class="hljs-built_in">document</span>; <span class="hljs-keyword">this</span>.selector = selector; <span class="hljs-keyword">this</span>.get = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">num</span>) </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>[num]; } <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; } <span class="hljs-comment">// 使用</span> $(<span class="hljs-string">'#show2'</span>).append(Ajquery(<span class="hljs-string">'#book'</span>).get(<span class="hljs-number">0</span>)); <span class="hljs-comment">// 因此 $('')获取到的就是一个类数组对象</span></code></pre> <hr> <p><strong>jQuery的无new构造原理</strong></p> <p>我们在构造jQuery对象的时候,并没有使用new来创建,但其实是在<code>jQuery</code>方法的内部,我们使用了<code>new</code>,这样就保证了当前对象内部就又了一个<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>对象,并且吧所有的属性和方法的键值对都映射到<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>上了,所以既可以通过链式取值,也可以通过索引取值。jquery除了实现了<code>类数组结构</code>, <code>方法的原型共享</code>,还实现了<code>静态和实例的共享</code>.</p> <p>javascript就是<code>函数式语言</code>,函数可以实现类,所以javascript不是一个严格的面向对象的语言。</p> <ul> <li>平时的情况</li> </ul> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="function ajquery(name){ this.name = name; } ajquery.prototype = function(){ say: function(){ return this.name; } } var a = new ajquery(); a.say();" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ajquery</span>(<span class="hljs-params">name</span>)</span>{ <span class="hljs-keyword">this</span>.name = name; } ajquery.prototype = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{ say: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.name; } } <span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> ajquery(); a.say();</code></pre> <ul> <li>但是在jquery中却不是这么来的。jQuery没有使用new运行符将jQuery显示的实例化,还是直接调用其函数</li> </ul> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="$().ready() $().noConflict()" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js">$().ready() $().noConflict()</code></pre> <ul> <li>如果要实现不用new直接获得实例</li> </ul> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="var aQuery = function(selector, context) { return new aQuery(); // 直接new一下 } aQuery.prototype = { name:function(){}, age:function(){} } // 如果是上诉的样子,直接new aQuery()则会导致死循环。" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-keyword">var</span> aQuery = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">selector, context</span>) </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> aQuery(); <span class="hljs-comment">// 直接new一下</span> } aQuery.prototype = { <span class="hljs-attr">name</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{}, <span class="hljs-attr">age</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{} } <span class="hljs-comment">// 如果是上诉的样子,直接new aQuery()则会导致死循环。</span></code></pre> <ul> <li>如何得到一个正确的实例呢,那么可以把jQuery类当作一个工厂方法来创建实例,把这个方法放到jQuery.prototye原型中,然后实例化这个方法,从而创建一个实例</li> </ul> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 下面就是jquery的写法了 jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }, // 但是问题又来了,init中的this指向的是实例init的原型,就导师了jquery类的this分离了, // 解决这个问题的方法是: jQuery.fn.init.prototype = jQuery.fn;" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-comment">// 下面就是jquery的写法了</span> jQuery = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> selector, context </span>) </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> jQuery.fn.init( selector, context, rootjQuery ); }, <span class="hljs-comment">// 但是问题又来了,init中的this指向的是实例init的原型,就导师了jquery类的this分离了,</span> <span class="hljs-comment">// 解决这个问题的方法是:</span> jQuery.fn.init.prototype = jQuery.fn;</code></pre> <p>以上就是jQuery无new构造的原理了</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 精简分析 var ajquery = function(name) { return new ajquery.prototype.init(name); } ajquery.prototype = { init: function(name) { this.name = name; return this; }, get: function() { return this.name; }, name: 'zjj' } ajquery.prototype.init.prototype = ajquery.prototype;//这里使得init内部的this跟ajquery类的this保持了一致。 console.log(ajquery('zmf').get()); // zmf" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs actionscript"><code><span class="hljs-comment">// 精简分析</span> <span class="hljs-keyword">var</span> ajquery = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(name)</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ajquery.prototype.init(name); } ajquery.prototype = { init: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(name)</span> </span>{ <span class="hljs-keyword">this</span>.name = name; <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; }, <span class="hljs-keyword">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.name; }, name: <span class="hljs-string">'zjj'</span> } ajquery.prototype.init.prototype = ajquery.prototype;<span class="hljs-comment">//这里使得init内部的this跟ajquery类的this保持了一致。</span> console.log(ajquery(<span class="hljs-string">'zmf'</span>).get()); <span class="hljs-comment">// zmf</span></code></pre> <hr> <blockquote><p>三、 ready和load事件</p></blockquote> <p>针对于文档的加载</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 一 $(function() { }) // 二 $(document).ready(function() { }) // 三 $(document).load(function() { })" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-comment">// 一</span> $(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ }) <span class="hljs-comment">// 二</span> $(<span class="hljs-built_in">document</span>).ready(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ }) <span class="hljs-comment">// 三</span> $(<span class="hljs-built_in">document</span>).load(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ })</code></pre> <p>在上面我们看到了一个是<code>ready</code>一个是<code>load</code>,那么这两个有什么区别呢?</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 我们先来看一个写DOM文档的加载过程吧 1. html 解析 2. 加载外部引用脚本和外部样式 3. 解析执行脚本 4. 构造DOM原型 // ready 5. 加载图片等文件 6. 页面加载完毕 // load" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-comment">// 我们先来看一个写DOM文档的加载过程吧</span> <span class="hljs-number">1.</span> html 解析 <span class="hljs-number">2.</span> 加载外部引用脚本和外部样式 <span class="hljs-number">3.</span> 解析执行脚本 <span class="hljs-number">4.</span> 构造DOM原型 <span class="hljs-comment">// ready</span> <span class="hljs-number">5.</span> 加载图片等文件 <span class="hljs-number">6.</span> 页面加载完毕 <span class="hljs-comment">// load</span></code></pre> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="document.addEventListener(&quot;DOMContentLoaded&quot;, function () { console.log('DOMContentLoaded回调') }, false); // 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。 window.addEventListener(&quot;load&quot;, function () { console.log('load事件回调') }, false); console.log('脚本解析一') //测试加载 $(function () { console.log('脚本解析二') }) console.log('脚本解析三') // 观察脚本加载的顺序 // test.html:34 脚本解析一 // test.html:41 脚本解析三 // test.html:38 脚本解析二 // test.html:26 DOMContentLoaded回调 // test.html:30 load事件回调" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"DOMContentLoaded"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'DOMContentLoaded回调'</span>) }, <span class="hljs-literal">false</span>); <span class="hljs-comment">// 当初始的 <a href="http://www.js-code.com/tag/html" title="浏览关于“HTML”的文章" target="_blank" class="tag_link">HTML</a> 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。</span> <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"load"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'load事件回调'</span>) }, <span class="hljs-literal">false</span>); <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'脚本解析一'</span>) <span class="hljs-comment">//测试加载</span> $(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'脚本解析二'</span>) }) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'脚本解析三'</span>) <span class="hljs-comment">// 观察脚本加载的顺序</span> <span class="hljs-comment">// test.html:34 脚本解析一</span> <span class="hljs-comment">// test.html:41 脚本解析三</span> <span class="hljs-comment">// test.html:38 脚本解析二</span> <span class="hljs-comment">// test.html:26 DOMContentLoaded回调</span> <span class="hljs-comment">// test.html:30 load事件回调</span></code></pre> <p>看完上面的过程我们不难看出ready是在文档加载完毕也就是DOM创建完毕后执行的,而load则是在页面加载完毕之后才执行的。<br />二者唯一的区别就是中间加了一个图片的加载,,但是图片等外部文件的加载确实很慢的呢。</p> <p>在平时种我们为了增加用户的体验效果,首先应该执行的是我们的处理框架的加载。而不是图片等外部文件的加载。我们应该越早处理DOM越好,我们不需要等到图片资源都加载后才去处理框架的加载,这样就能增加用户的体验了。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 源码分析 jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); if ( document.readyState === &quot;complete&quot; ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready ); } else { document.addEventListener( &quot;DOMContentLoaded&quot;, completed, false ); window.addEventListener( &quot;load&quot;, completed, false ); } } return readyList.promise( obj ); };" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-comment">// 源码分析</span> jQuery.ready.promise = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> obj </span>) </span>{ <span class="hljs-keyword">if</span> ( !readyList ) { readyList = jQuery.Deferred(); <span class="hljs-keyword">if</span> ( <span class="hljs-built_in">document</span>.ready<a href="http://www.js-code.com/tag/state" title="浏览关于“State”的文章" target="_blank" class="tag_link">State</a> === <span class="hljs-string">"comp<a href="http://www.js-code.com/tag/let" title="浏览关于“let”的文章" target="_blank" class="tag_link">let</a>e"</span> ) { <span class="hljs-comment">// Handle it asynchronously to allow scripts the opportunity to delay ready</span> setTimeout( jQuery.ready ); } <span class="hljs-keyword">else</span> { <span class="hljs-built_in">document</span>.addEventListener( <span class="hljs-string">"DOMContentLoaded"</span>, completed, <span class="hljs-literal">false</span> ); <span class="hljs-built_in">window</span>.addEventListener( <span class="hljs-string">"load"</span>, completed, <span class="hljs-literal">false</span> ); } } <span class="hljs-keyword">return</span> readyList.promise( obj ); };</code></pre> <p><strong>DOM文档是否加载完毕处理方法</strong></p> <ul> <li>DOMContentLoaded</li> </ul> <p>当<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>文档内容加载完毕后触发,并不会等待图像、外部引用文件、样式表等的完全加载。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<script> document.addEventListener(&quot;DOMContentLoaded&quot;, function(event) { console.log(&quot;DOM fully loaded and parsed&quot;); });</p> <p> for(var i=0; i<1000000000; i++){ // 这个同步脚本将延迟DOM的解析。 // 所以DOMContentLoaded事件稍后将启动。 } </script>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript">&lt;script&gt; <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"DOMContentLoaded"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"DOM fully loaded and parsed"</span>); }); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">1000000000</span>; i++){ <span class="hljs-comment">// 这个同步脚本将延迟DOM的解析。</span> <span class="hljs-comment">// 所以DOMContentLoaded事件稍后将启动。</span> } &lt;<span class="hljs-regexp">/script&gt;</span></code></pre> <p>该事件的浏览器支持情况是在IE9及以上支持。</p> <blockquote><p>兼容不支持该事件的浏览器</p></blockquote> <ul> <li>readystatechange</li> </ul> <p>在IE8中能够使用readystatechange来检测DOM文档是否加载完毕。</p> <p>对于跟早的IE,可以通过每隔一段时间执行一次<code>document.documentElement.doScroll("left")</code>来检测这一状态,因为这条代码在DOM加载完毕之前执行时会抛出错误(throw an error)。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="document.onreadystatechange = subSomething;//当页面加载状态改变的时候执行这个方法. function subSomething() { if(document.readyState == &quot;complete&quot;){ //当页面加载状态为完全结束时进入 //你要做的操作。 } } // 用这个可以做一下等待网站图片或者其他东西加载完以后的操作,比如加载时我们可以调用加载动画,当complete也就是加载完成时我们让加载动画隐藏,这样只是一个小例子。还是很完美的。" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-built_in">document</span>.onreadystatechange = subSomething;<span class="hljs-comment">//当页面加载状态改变的时候执行这个方法.</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subSomething</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">if</span>(<span class="hljs-built_in">document</span>.readyState == <span class="hljs-string">"complete"</span>){ <span class="hljs-comment">//当页面加载状态为完全结束时进入 </span> <span class="hljs-comment">//你要做的操作。</span> } } <span class="hljs-comment">// 用这个可以做一下等待网站图片或者其他东西加载完以后的操作,比如加载时我们可以调用加载动画,当complete也就是加载完成时我们让加载动画隐藏,这样只是一个小例子。还是很完美的。</span></code></pre> <blockquote><p>针对IE的加载检测</p></blockquote> <p>Diego Perini 在 2007 年的时候,报告了一种检测 IE 是否加载完成的方式,使用 doScroll 方法调用,详情可见<a href="http://javascript.nwbox.com/IEContentLoaded/" rel="nofollow noreferrer" target="_blank">http://javascript.nwbox.com/I...</a>。<br />原理就是对于 IE 在非 iframe 内时,只有不断地通过能否执行 doScroll 判断 DOM 是否加载完毕。在上述中间隔 50 毫秒尝试去执行 doScroll,注意,由于页面没有加载完成的时候,调用 doScroll 会导致异常,所以使用了 try -catch 来捕获异常。<br />结论:所以总的来说当页面 DOM 未加载完成时,调用 doScroll 方法时,会产生异常。那么我们反过来用,如果不异常,那么就是页面DOM加载完毕了。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// Ensure firing before onload, maybe late but safe also for iframes document.attachEvent( &quot;onreadystatechange&quot;, completed ); // A fallback to window.onload, that will always work window.attachEvent( &quot;onload&quot;, completed ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { // 非iframe中 top = window.frameElement == null &amp;&amp; document.documentElement; } catch(e) {} if ( top &amp;&amp; top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll(&quot;left&quot;); } catch(e) { // 每个50ms执行一次 return setTimeout( doScrollCheck, 50 ); } // 分离所有dom就绪事件 detach(); // and execute any waiting functions jQuery.ready(); } })(); }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-comment">// Ensure firing before onload, maybe late but safe also for iframes</span> <span class="hljs-built_in">document</span>.attachEvent( <span class="hljs-string">"onreadystatechange"</span>, completed ); <span class="hljs-comment">// A fallback to window.onload, that will always work</span> <span class="hljs-built_in">window</span>.attachEvent( <span class="hljs-string">"onload"</span>, completed ); <span class="hljs-comment">// If IE and not a frame</span> <span class="hljs-comment">// continually check to see if the document is ready</span> <span class="hljs-keyword">var</span> top = <span class="hljs-literal">false</span>; <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 非iframe中</span> top = <span class="hljs-built_in">window</span>.frameElement == <span class="hljs-literal">null</span> &amp;&amp; <span class="hljs-built_in">document</span>.documentElement; } <span class="hljs-keyword">catch</span>(e) {} <span class="hljs-keyword">if</span> ( top &amp;&amp; top.doScroll ) { (<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doScrollCheck</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">if</span> ( !jQuery.isReady ) { <span class="hljs-keyword">try</span> { <span class="hljs-comment">// Use the trick by Diego Perini</span> <span class="hljs-comment">// http://javascript.nwbox.com/IEContentLoaded/</span> top.doScroll(<span class="hljs-string">"left"</span>); } <span class="hljs-keyword">catch</span>(e) { <span class="hljs-comment">// 每个50ms执行一次</span> <span class="hljs-keyword">return</span> setTimeout( doScrollCheck, <span class="hljs-number">50</span> ); } <span class="hljs-comment">// 分离所有dom就绪事件</span> detach(); <span class="hljs-comment">// and execute any waiting functions</span> jQuery.ready(); } })(); }</code></pre> <blockquote><p>三、 解决$的冲突</p></blockquote> <ul> <li>$太火热,jQuery采用$作为命名空间,不免会与别的库框架或者插件相冲突。</li> </ul> <p>解决方案–– <code>noConflict函数</code>。</p> <p>引入jQuery运行这个<code>noConflict</code>函数将变量$的控制权让给第一个实现它的那个库,确保jQuery不会与其他库的$对象发生冲突。<br />在运行这个函数后,就只能使用<code>jQuery</code>变量访问<code>jQuery对象</code>。例如,在要用到<code>$("aaron")</code>的地方,就必须换成<code>jQuery("aaron")</code>,因为$的控制权已经让出去了。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="// jquery导入 jQuery.noConflict(); // 使用 jQuery jQuery(&quot;aaron&quot;).show(); // 使用其他库的 $() // 别的库导入 $(&quot;aaron&quot;).style.display = ‘block’;" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-comment">// jquery导入</span> jQuery.noConflict(); <span class="hljs-comment">// 使用 jQuery</span> jQuery(<span class="hljs-string">"aaron"</span>).show(); <span class="hljs-comment">// 使用其他库的 $()</span> <span class="hljs-comment">// 别的库导入</span> $(<span class="hljs-string">"aaron"</span>).style.display = ‘block’;</code></pre> <p>这个函数必须在你导入jQuery文件之后,并且在导入另一个导致冲突的库之前使用。当然也应当在其他冲突的库被使用之前,除非jQuery是最后一个导入的。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="(function(window, undefined) { var // Map over jQuery in case of overwrite // 设置别名,通过两个私有变量映射了 window 环境下的 jQuery 和 $ 两个对象,以防止变量被强行覆盖 _jQuery = window.jQuery, _$ = window.$; jQuery.extend({ // noConflict() 方法让出变量 $ 的 jQuery 控制权,这样其他脚本就可以使用它了 // 通过全名替代简写的方式来使用 jQuery // deep -- 布尔值,指示是否允许彻底将 jQuery 变量还原(移交 $ 引用的同时是否移交 jQuery 对象本身) noConflict: function(deep) { // 判断全局 $ 变量是否等于 jQuery 变量 // 如果等于,则重新还原全局变量 $ 为 jQuery 运行之前的变量(存储在内部变量 _$ 中) if (window.$ === jQuery) { // 此时 jQuery 别名 $ 失效 window.$ = _$; } // 当开启深度冲突处理并且全局变量 jQuery 等于内部 jQuery,则把全局 jQuery 还原成之前的状况 if (deep &amp;&amp; window.jQuery === jQuery) { // 如果 deep 为 true,此时 jQuery 失效 window.jQuery = _jQuery; } // 这里返回的是 jQuery 库内部的 jQuery 构造函数(new jQuery.fn.init()) // 像使用 $ 一样尽情使用它吧 return jQuery; } }) }(window)" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript">(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">window, undefined</span>) </span>{ <span class="hljs-keyword">var</span> <span class="hljs-comment">// <a href="http://www.js-code.com/tag/map" title="浏览关于“Map”的文章" target="_blank" class="tag_link">Map</a> over jQuery in case of overwrite</span> <span class="hljs-comment">// 设置别名,通过两个私有变量映射了 window 环境下的 jQuery 和 $ 两个对象,以防止变量被强行覆盖</span> _jQuery = <span class="hljs-built_in">window</span>.jQuery, _$ = <span class="hljs-built_in">window</span>.$; jQuery.extend({ <span class="hljs-comment">// noConflict() 方法让出变量 $ 的 jQuery 控制权,这样其他脚本就可以使用它了</span> <span class="hljs-comment">// 通过全名替代简写的方式来使用 jQuery</span> <span class="hljs-comment">// deep -- 布尔值,指示是否允许彻底将 jQuery 变量还原(移交 $ 引用的同时是否移交 jQuery 对象本身)</span> noConflict: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">deep</span>) </span>{ <span class="hljs-comment">// 判断全局 $ 变量是否等于 jQuery 变量</span> <span class="hljs-comment">// 如果等于,则重新还原全局变量 $ 为 jQuery 运行之前的变量(存储在内部变量 _$ 中)</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.$ === jQuery) { <span class="hljs-comment">// 此时 jQuery 别名 $ 失效</span> <span class="hljs-built_in">window</span>.$ = _$; } <span class="hljs-comment">// 当开启深度冲突处理并且全局变量 jQuery 等于内部 jQuery,则把全局 jQuery 还原成之前的状况</span> <span class="hljs-keyword">if</span> (deep &amp;&amp; <span class="hljs-built_in">window</span>.jQuery === jQuery) { <span class="hljs-comment">// 如果 deep 为 true,此时 jQuery 失效</span> <span class="hljs-built_in">window</span>.jQuery = _jQuery; } <span class="hljs-comment">// 这里返回的是 jQuery 库内部的 jQuery 构造函数(new jQuery.fn.init())</span> <span class="hljs-comment">// 像使用 $ 一样尽情使用它吧</span> <span class="hljs-keyword">return</span> jQuery; } }) }(<span class="hljs-built_in">window</span>)</code></pre> <p>使用实例:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<script src=&quot;prototype.js&quot;></script>//1.包含jQuery之外的库(比如Prototype)<br /> <script src=&quot;jquery.js&quot;></script>//2.包含jQuery库取得对$的使用权<br /> <script> jQuery.noConflict();//3.调用noConflict()方法,让出$,把控制权让给最先包含的库 </script><br /> <script src=&quot;myscript.js&quot;></script>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"prototype.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>//1.包含jQuery之外的库(比如Prototype) <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"jquery.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>//2.包含jQuery库取得对$的使用权 <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="actionscript"> jQuery.noConflict();<span class="hljs-comment">//3.调用noConflict()方法,让出$,把控制权让给最先包含的库</span> </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"myscript.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre> <p>让出$控制权后,需要使用jQuery方法时,则不能用$来调用了,要用jQuery。或者通过定义新的名称来代替$符号。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="var jq=jQuery.noConflict();" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs nginx"><code style="word-break: break-word; white-space: initial;"><span class="hljs-attribute">var</span> jq=jQuery.<span class="hljs-literal">no</span>Conflict();</code></pre> <p>另外还有一个技巧,可以再.ready()方法中使用$。它的回调函数可以接收一个参数,这个参数为jQuery对象本身,可以重新命名jQuery为$,这样也是不会造成冲突的。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="jQuery.(document).ready(function($){ //这里可以正常使用$ })" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs javascript"><code>jQuery.(<span class="hljs-built_in">document</span>).ready(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">$</span>)</span>{ <span class="hljs-comment">//这里可以正常使用$ </span> })</code></pre> <blockquote><p> <a href="https://blog.csdn.net/SUFEIDEYEYE/article/details/51810912" rel="nofollow noreferrer" target="_blank">jQuery源码学习系列</a></p> <p><a href="https://www.cnblogs.com/coco1s/p/5261646.html" rel="nofollow noreferrer" target="_blank">一篇不错的解析博客</a></p> </blockquote> <p></code></p>

总结

以上是脚本宝典为你收集整理的

jquery源码学习 (一) 概况

全部内容,希望文章能够帮你解决

jquery源码学习 (一) 概况

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过