検索
ホームページウェブフロントエンドjsチュートリアル中級および上級の JSER_jquery の jQuery 1.5 ソース コード解釈

几乎很难从jQuery分离其中的一部分功能。所以在这里我分享下应该读 jQuery 源码的一些成果,以及读源码的方法。啃代码是必须的。

1. 代码折叠是必须的。

因此必须在支持语法折叠的编辑器里打开源码。 根据折叠层次,我们可以很快知道: 所有 jQuery 的代码都在一个函数中:   

<div>
<span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">( window, undefined ) {<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> jQuery 代码</span><span style="COLOR: #008000"></span><span style="COLOR: #000000"><br><br>})(window);</span>
</div>

这样可以避免内部对象污染全局。传入的参数1是 window, 参数2是 undefined , 加快js搜索此二对象的速度。

2.  接着打开第一级折叠。

可以发现 jQuery 代码是按这样顺序来组织:

  • 定义 jQuery 函数 ( 代码  20 - 1081 行)
  • 生成 jQuery.support (代码 1083 - 1276 行)
  • 和 data 有关扩展 (代码 1279 - 1510 行)
  • 和队列有关扩展 (代码 1514 - 1605 行)
  • 和属性有关扩展 (代码 1609 - 1988 行)
  • 和事件有关扩展 (代码 1993 - 3175 行)
  • 内部的Sizzle CSS Selector Engine (代码 3183 - 4518 行)
  • 和节点有关扩展 (代码 4520 - 5492 行)
  • 和样式有关扩展 (代码 5497 - 5825 行)
  • 和ajax有关扩展 (代码 5830 - 7172 行)
  • 和效果有关扩展 (代码 7176 - 7696 行)
  • 和定位有关扩展 (代码 7700 - 8065 行)

下面的模块可以用上面的模块,上面的模块不需要下面的模块

3.   定义 jQuery 函数 ( 代码  20 - 1081 行)

总的代码是这样的框架:

<div>
<span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> jQuery </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">() {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 创建 jQuery 对象</span><span style="COLOR: #008000"><br></span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> jQuery </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">( selector, context ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br> };<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 创建 jQuery.fn 对象</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> jQuery.fn </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jQuery.prototype </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> };<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 声明 jQuery.extend </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> jQuery.extend </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jQuery.fn.extend </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">() {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> };<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 使用 jQuery.extend 扩展自己</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> jQuery.extend({<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br> });<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 浏览器方面的一些琐碎</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 定义全局对象</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> (window.jQuery </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> window.$ </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jQuery);<br><br>})();</span>
</div>

从这里知道: 平时所用的 $ 其实就是 jQuery 函数的别名。

3.1 jQuery对象 (代码 23 - 26 行)

  jQuery对象似乎一直都是这东西:

<div>
<span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> jQuery </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">( selector, context ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 实际上 jQuery 对象是 jQuery.fn.init 返回的。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> jQuery.fn.init( selector, context, rootjQuery );<br>} </span>
</div>

这个函数表示: 要想知道函数 jQuery 是什么东西,必须看   jQuery.fn.init  对象。

同时这也解释了为什么写代码不需要 new jQuery。

再看第29行 - 97行, 都是一些变量声明,这些变量在下面的函数用到。提取变量的好处: 对正则节约编译的时间, 同时能在压缩的时候获得更小的结果。

3.2 jQuery.fn 对象 (代码 99 - 320 行)

这个fn 其实是 jQuery.prototype ,这也是为啥jQuery.fn 就是扩展 jQuery对象的唯一原因。

肯能有人会疑问, jQuery 返回 new jQuery.fn.init, 也就是说,平时的函数应该是 jQuery.fn.init.prototype 所有的成员,不是 jQuery.prototype 成员。当然原因也很简单: jQuery.fn.init.prototype === jQuery.prototype (代码 322  行)

jQuery 对js对象处理和中国人讲话一样绕。这里总结下到底 jQuery 对象是个什么家伙。

jQuery 是普通函数, 返回 jQuery.fn.init 对象的实例( new jQuery.fn.init() )。

然后 jQuery.fn === jQuery.prototype === jQuery.fn.init.prototype ,最后, jQuery返回的对象的成员和 jQuery.fn 的成员匹配。

jQuery.fn 下有很多成员,下面稍作介绍:

  init - 初始化(下详细说明)

  constructor - 手动指定一个构造函数。 因为默认是  jQuery.fn.init

  length - 让这个对象更接近一个 原生的数组

  size - 返回 length

  toArray - 通过 Array.prototype slice 实现生成数组

  get - 即 this[ num ] ,当然作了下 参数索引 的处理。

  pushStack - 加入一个元素

  ready - 浏览器加载后执行(下详细说明)

  end - 通过保存的 prevObject 重新返回

  each - 参考 http://www.cnblogs.com/Fooo/archive/2011/01/11/1932900.html

参考 http://www.cnblogs.com/rubylouvre/archive/2009/11/21/1607632.html

3.3 jQuery.fn.init (代码 101 - 211 行)

  jQuery.fn.init 就是所谓的 $ 函数。 也就是说,平常的 $("#id") 就是  new jQuery.fn.init("#id");

这个函数很长,但代码覆盖率小。

<div>
<span style="COLOR: #000000"> init: </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">( selector, context, rootjQuery ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 参数: selector 选择器</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> context 上下文</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> rootjQuery 父节点</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 $("")、 $(null) 和 $(undefined)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">selector ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 $(DOMElement)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( selector.nodeType ) {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 直接扔数组中, 就搞定了。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.context </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> selector;<br> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.length </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 $("body") body 元素只存在一次,单独找它</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( selector </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">body</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">context </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> document.body ) {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 同样扔数组中, 顺便把 selector 更新更新。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.context </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> document;<br> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> document.body;<br> thisis.selector </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">body</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.length </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 $(HTML 代码 或者是 css 选择器) </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #0000ff">typeof</span><span style="COLOR: #000000"> selector </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">string</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> <br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 $(函数)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( jQuery.isFunction( selector ) ) {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果是函数,则执行 $(document).ready , 这样 $(document).ready(func) 简为 $(func)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> rootjQuery.ready( selector );<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果传入的是一个 Dom列表 ( getElementsByTagName 结果 ) 则转为 jQuery 数组。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> jQuery.makeArray( selector, </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000"> );<br>}</span>
</div>
<div>
<span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 这部分代码是 上段中 略 的 也就是说是 jQuery(字符串) 处理。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 检查是否字符串是常用选择器 (/^(?:[^)[^>]*$|#([\w\-]+)$)/)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">match </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> quickExpr.exec( selector );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 检查是否正确匹配</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( match </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> (match[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">context) ) {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理: $(html) -> $(array)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( match[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">] ) {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 获取正文,默认 document</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> context </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> context </span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> jQuery </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"> context[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] : context;<br> doc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (context </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"> context.ownerDocument </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> context : document);<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果传入简单的 "", ( /^(?:)?$/)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> ret </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rsingleTag.exec( selector );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 返回 createElement("tag")</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> jQuery.merge( </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">, selector );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理: $("#id")</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> {<br> elem </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> document.getElementById( match[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">] );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 因为有的浏览器 getElementById 不只返回 id匹配的,所以做检查。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 $("标签")</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">context </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">rnonword.test( selector ) ) {<br> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.selector </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> selector;<br> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.context </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> document;<br> selector </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> document.getElementsByTagName( selector );<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> jQuery.merge( </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">, selector );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">处理: $(选择器, $(...))</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">context </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> context.jquery ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> (context </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> rootjQuery).find( selector );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理: $(选择器, 上下文)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (相当于: $(上下文).find(选择器)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.constructor( context ).find( selector );<br> }</span>
</div>

3.4 jQuery.fn.extend (代码 324 - 386 行)

这个函数用于 扩展函数

函数中含多个参数判断,为了使用可以更灵活。

基本原理就是for(in),这里不具体介绍了。

3.5 jQuery.noConflict (代码 389 - 399 行 )
<div>
<span style="COLOR: #000000">noConflict: </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">( deep ) {<br> window.$ </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> _$;<br><br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( deep ) {<br> window.jQuery </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> _jQuery;<br> }<br><br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> jQuery;<br> },</span>
</div>

不多解释了,就是让 jQuery 恢复为全局的对象。

3.6 jQuery.ready (代码 407 -381 行)

 其中有2个函数:

jQuery.ready 触发执行 readyList 中的所有函数

jQuery.bindReady  初始化让 jQuery.ready 成功执行

<div>
<span style="COLOR: #000000">bindReady: </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">() {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果已经执行 bindReady 则返回。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( readyBound ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br> }<br><br> readyBound </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果页面已经加载, 马上执行 jQuery.ready</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( document.readyState </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">complete</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> setTimeout( jQuery.ready, </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> );<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 标准浏览器支持 DOMContentLoaded</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( document.addEventListener ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 你懂的</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> document.addEventListener( </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">DOMContentLoaded</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, DOMContentLoaded, </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 为什么还要 load ? , 因为有些时候 DOMContentLoaded 失败(如 iframe) ,而 load 总是会成功, 所以,同时处理 DOMContentLoaded load, 在 jQuery.ready 中会删除监听函数,保证最后这个函数只执行一次</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> window.addEventListener( </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">load</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, jQuery.ready, </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> IE浏览器( IE 8 以下)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( document.attachEvent ) {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 使用 onreadystatechange</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> document.attachEvent(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">onreadystatechange</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, DOMContentLoaded);<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 同理</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> window.attachEvent( </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">onload</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, jQuery.ready );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果 IE 下且非 iframe, 这里有个技巧。 见 doScrollCheck();</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 原理: 浏览器在没加载时 设置 scrollLeft 会错误,所哟每隔1秒厕所 是否 scrollLeft 成功,如果发现成功,则执行 jQuery.ready 。但这只对非 frame 会有用。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> toplevel </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br><br> </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br> toplevel </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> window.frameElement </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br> } </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(e) {}<br><br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( document.documentElement.doScroll </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> toplevel ) {<br> doScrollCheck();<br> }<br> }<br> },</span>
</div>

bindReady 函数在执行 ready 时执行。(jQuery 1.4 之前版本都是 绝对执行,不管需不需要 ready 函数)

4.  生成 jQuery.support (代码 1083 - 1276 行)

   人人都说 jQuery.support 是个好东西。确实,这东西可以解决很多兼容问题。

    jQuery.support 是基于检测的浏览器兼容方式。也就是说,创建一个元素, 看这个元素是否符合一些要求。

  比如测试元素是否支持checkOn属性,只要先 set check = 'on' 然后看浏览器是否 get check == 'on'。

  此部分源码不具体介绍了。

5.和 data 有关扩展 (代码 1279 - 1510 行)

     jQuery的 data() 用于存储一个字典。而这些数据最后都保存在 jQuery.cache  ( 代码 1283 行) ,  全局对象存在 windowData  ( 代码 1279  行)  。

   但如果正确根据对象找到其在 jQuery.cache  的存储对象? 这就是 expando 字符串。

比如一个对象:  elem 。

满足:   elem.expando = "jQuery12321";

那么    jQuery.cache["jQuery12321"]  就是存储这个 elem 数据的对象。

实际上, 不是 elem.expando 表示键值,而是 elem[ jQuery.expando ] 表示。

而一个对象数据又是一个字典,所以最后执行 jQuery.data(elem, 'events') 后就是:

jQuery.cache[elem[jQuery.expando]]['events'] 的内容   (jQuery.cache[elem[jQuery.expando]] = {} )

6.和队列有关扩展 (代码 1514 - 1605 行)

队列是 jQuery 1.5 新增的。

主要用于特效等需要等待执行的时候。

队列主要操作就是 进队queue 出队dequeue

jQuery 队列内的数据:

如果没有执行:

[将执行的1, 将执行的2]

现在开始执行 , 如果 type 为空或 "fx", 队列内数据:

["inprogress", 将执行的2]

执行完之后:

["将执行的2]

以上的这些数据都存在 jQuery.data(obj, (type || "fx") + "queue") (代码 1520 - 1522行)

jQuery.delay 则用于延时执行一个函数。相当于把原来队列更新为 setTImeout 后的结果。 (代码 1589 -1598 行)

7.和属性有关扩展 (代码 1609 - 1988 行)

从这里开始,需要了解一个函数jQuery.access。对于 attr ,css 之类的函数,如果需要返回值,只返回第一个元素的值,如果是设置值,则设置每个元素的值。这个神奇的效果就是 jQuery.access 搞定的。

jQuery.access代码在 794 - 819 行

jQuery大部分函数都是依赖 jQuery.access 实现的,比如有一个函数 XX,对用户而言,调用的是 jQuery.fn.XX, 而这个函数需要对多个元素(jQuery数组内的所有的节点) 操作,或者对1个元素操作, 通过 jQuery.access 转换(不一定都是),最后只写对1个元素的操作。这1个元素的操作往往是 jQuery.XX 函数,因此,我们往往能看到即存在 jQuery.XX, 又存在 jQuery.fn.XX, 而其实 jQuery.fn.XX 都是依靠 jQuery.XX 的,或者说jQuery.XX是底层函数, jQuery.fn.XX 是方便用户的工具 。

jQuery.fn.attr 这个函数(代码 1632 - 1634 行) 只有1句话,真正的实现是  jQuery.attr (代码 1880 - 1988)

又是一个大于100行的函数

<div>
<span style="COLOR: #000000">attr: </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">( elem, name, value, pass ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 检查是否为 nodeType 为 Element</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">elem </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> elem.nodeType </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> elem.nodeType </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> elem.nodeType </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> undefined;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果这个属性需要特殊对待。 height/width/left 等属性需特殊计算</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( pass </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> name </span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000"> jQuery.attrFn ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> jQuery(elem)[name](value);<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 检查是否为 XML 还 HTML </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> notxml </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elem.nodeType </span><span style="COLOR: #000000">!==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">jQuery.isXMLDoc( elem ),<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Whether we are setting (or getting)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> set </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> value </span><span style="COLOR: #000000">!==</span><span style="COLOR: #000000"> undefined;<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 修正名字, 比如 float 改 cssFloat</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> name </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> notxml </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> jQuery.props[ name ] </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> name;<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 只有在节点的时候执行。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( elem.nodeType </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 在 IE7- 下, href src 属性直接获取会返回绝对位置,而不是真实的位置字符串,</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 要获得它们的真实值,需要 elem.getAttribute("href", 2);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> special </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rspecialurl.test( name );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Safari 误报默认选项。通过获取父元素的已选择索引来修复。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( name </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">selected</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">jQuery.support.optSelected ) {<br> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> parent </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elem.parentNode;<br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( parent ) {<br> parent.selectedIndex;<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 对 optgroups ,同理</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( parent.parentNode ) {<br> parent.parentNode.selectedIndex;<br> }<br> }<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 检查属性是否存在, 有些时候 name in elem 会失败,所以多次测试。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( (name </span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000"> elem </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> elem[ name ] </span><span style="COLOR: #000000">!==</span><span style="COLOR: #000000"> undefined) </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> notxml </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">special ) {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果设置属性</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( set ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 在IE, 不能设置属性 type 。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( name </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">type</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> rtype.test( elem.nodeName ) </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> elem.parentNode ) {<br> jQuery.error( </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">type property can't be changed</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> );<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果 value === null, 表示移除属性</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( value </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( elem.nodeType </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> ) {<br> elem.removeAttribute( name );<br> }<br><br> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> {<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 一切属性设置就是1句话。。。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> elem[ name ] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> value;<br> }<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 表单索引元素获取需要 getAttributeNode( name ).nodeValue</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( jQuery.nodeName( elem, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">form</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ) </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> elem.getAttributeNode(name) ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> elem.getAttributeNode( name ).nodeValue;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> elem.tabIndex 特殊处理</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( name </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">tabIndex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> attributeNode </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elem.getAttributeNode( </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">tabIndex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> );<br><br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> attributeNode </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> attributeNode.specified </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"><br> attributeNode.value :<br> rfocusable.test( elem.nodeName ) </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> rclickable.test( elem.nodeName ) </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> elem.href </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"><br> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> :<br> undefined;<br> }<br><br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> elem[ name ];<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 style 属性</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">jQuery.support.style </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> notxml </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> name </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">style</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( set ) {<br> elem.style.cssText </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">""</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> value;<br> }<br><br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> elem.style.cssText;<br> }<br><br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( set ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 这里除了 IE, 其它属性使用标准 setAttribute </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> elem.setAttribute( name, </span><span style="COLOR: #000000">""</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> value );<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果属性不存在,返回 undefined, 而不是 null 或 "" 之类的。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">elem.attributes[ name ] </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> (elem.hasAttribute </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">elem.hasAttribute( name )) ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> undefined;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 见上</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> attr </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">jQuery.support.hrefNormalized </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> notxml </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> special </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Some attributes require a special call on IE</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> elem.getAttribute( name, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"> ) :<br> elem.getAttribute( name );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 同上</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> attr </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"> undefined : attr;<br> }<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果不是 DOM 元素,检查处理。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( set ) {<br> elem[ name ] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> value;<br> }<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> elem[ name ];<br> }</span>
</div>

windowData

8.和事件有关扩展 (代码 1993 - 3175 行)

   8.1 事件

      平时我们都是调用 click(func) 之类的函数, 而其实这些都是工具函数,真正和事件挂钩的函数是

  jQuery.fn.bind - 调用 jQuery.event.add

 jQuery.fn.unbind - 调用 jQuery.event.remove

 jQuery.fn.trigger - 调用 jQuery.event.trigger

 jQuery.fn.one - 调用 jQuery.fn.bind,Query.fn.unbind

要想知道jQuery的事件原理,必须读 jQuery.event.add (代码 2012 - 2155  行)

<div>
<span style="COLOR: #000000">追加: </span><span style="COLOR: #0000ff">関数</span><span style="COLOR: #000000">(elem、types、handler、data) {<br><br> </span><span style="COLOR: #008000">/ /</span><span style="COLOR: #008000"> はノード上でのみ動作します。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( elem.nodeType </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span> <span style="COLOR: #000000">3</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> elem.nodeType </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> IE はできません代わりにウィンドウを渡すとオブジェクトがコピーされます。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( jQuery.isWindow( elem ) </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> ( elem </span><span style="COLOR: #000000">!==</span><span style="COLOR: #000000"> ウィンドウ </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">elem.frameElement ) ) {<br> elem </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> window;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> handler === false の場合、つまりイベントを防ぐということは、 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> このように、bind("evt", false である限り) ); このイベントを防ぎます。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( ハンドラー </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> ) {<br> ハンドラー </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> returnFalse;<br> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">ハンドラー) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br> }<br> <br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> handleObjIn は内部処理ハンドル、handleObj は直接使用される処理ハンドルです。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> handleObjIn, handleObj;<br><br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( handler.handler ) {<br> handleObjIn </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ハンドラー;<br> ハンドラー </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> handleObjIn.handler;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 関数の一意の GUID を生成します。以下に詳細を紹介します。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">handler.guid ) {<br> handler.guid </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jQuery.guid</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">;<br> }<br><br> </span><span style="COLOR: #008000">// </span><span style="COLOR: #008000"> ノードのデータを取得します。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> elemData </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jQuery.data( elem );<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> データがない場合は直接リターンします。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">elemData ) {<br> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ネイティブ JS オブジェクトとの混同を避けてください。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">eventKey </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elem.nodeType </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">イベント</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> : </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">__events__ </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ここが鍵です。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> elemData はデータが保存される場所であり、elemData[eventKey] は現在のデータを保存するオブジェクトですイベント。 elemData.handle は、現在バインドされているすべての関数の配列です。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> つまり、関数をバインドするときに、この関数を elemData.handle に置きます。イベントがトリガーされると、elemData.handle 内の関数が走査されて実行されます。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ネイティブ DOM の内部にも関数とイベントの配列があるため、なぜこれが行われるのか疑問に思う人もいるかもしれません。すべての機能はトリガー後に実行されます。答えはまだ互換性があります。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 標準ブラウザは addEventListener を使用します</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> IE はattachEvent</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> を使用しており、これら 2 つはまだ存在しますギャップです。 addEventListener が関数を実行する順序は関数が追加された順序ですが、attachEvent が関数を実行する順序は関数が追加された順序と逆であるためです。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> jQuery はカスタム ハンドラー配列を使用します: </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ネイティブ イベントは 1 回だけバインドされるため、イベントがトリガーされた後、配列内の関数が手動で実行されます。これにより互換性が確保されます。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 同時に、どの関数がバインドされているかを知ることもでき、これにより、トリガー機能。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br> イベント </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elemData[eventKey ],<br>eventHandle </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elemData.handle;<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> いくつかの関数。 。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #0000ff"></span><span style="COLOR: #000000"> イベントの種類 </span><span style="COLOR: #000000">= ==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">関数</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> ) {<br>eventHandle </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> events.handle;<br> events </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> events.events;<br><br> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">イベント ) {<br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">elem.nodeType ) { <br> elemData[eventKey ] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elemData </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">関数</span><span style="COLOR: #000000">(){};<br> }<br><br> elemData.events </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> イベント </span><span style="COLOR: #000000">= </span><span style="COLOR: #000000"> {};<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 初めて実行する場合は、eventHandle</span> を作成する必要があります<span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">eventHandle ) {<br><br> </span><span style="COLOR: #008000"> //</span><span style="COLOR: #008000">eventHandle は、実際にネイティブ イベントにバインドされる関数です。この関数は events.hadlers を実行するために使用されます。 </span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> elemData.handle </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> イベントハンドル </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">() {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> トリガーの 2 番目のイベントと when</span><span style="COLOR: #008000"><br></span> <span style="COLOR: #000000"></span>//<span style="COLOR: #008000"></span> ページがアンロードされた後にイベントが呼び出されます<span style="COLOR: #008000"></span><span style="COLOR: #008000"><br></span> <span style="COLOR: #000000"></span>return<span style="COLOR: #0000ff"> </span> <span style="COLOR: #000000"></span>typeof<span style="COLOR: #0000ff"></span> jQuery <span style="COLOR: #000000"></span>!==<span style="COLOR: #000000"></span> <span style="COLOR: #000000"></span>"<span style="COLOR: #000000"></span>未定義<span style="COLOR: #000000"></span>"<span style="COLOR: #000000"></span> <span style="COLOR: #000000"></span>&&<span style="COLOR: #000000"></span> <span style="COLOR: #000000"></span>!<span style="COLOR: #000000"></span>jQuery.event.triggered <span style="COLOR: #000000"></span>?<span style="COLOR: #000000"> </span><span style="COLOR: #000000"> jQuery.event.handle.apply(eventHandle.elem, argument ) :<br> 未定義;<br> };<br> }<br><br> <br></span>//<span style="COLOR: #008000"></span> 関数とネイティブをバインドして、関数が現在のスコープで実行可能であることを確認します。<span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> eventHandle.elem </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> elem;<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 处理 jQuery(...).bind("mouseover mouseout", fn);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> types </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> types.split(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><br> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> type, i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">, namespaces;<br><br> </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> ( (type </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> types[ i</span><span style="COLOR: #000000">  </span><span style="COLOR: #000000"> ]) ) {<br> handleObj </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> handleObjIn </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"><br> jQuery.extend({}, handleObjIn) :<br> { handler: handler, data: data };<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 略</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> <br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 绑定 type guid</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> handleObj.type </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> type;<br> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">handleObj.guid ) {<br> handleObj.guid </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> handler.guid;<br> }<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 获取当前的函数数组。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"> handlers </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> events[ type ],<br> special </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jQuery.event.special[ type ] </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> {};<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果第一次,则创建这个数组。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">handlers ) {<br> handlers </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> events[ type ] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> [];<br><br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 特殊事件要执行 setup 而不是标准 addEventListener。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 此行用来支持自定义的事件。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">special.setup </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> special.setup.call( elem, data, namespaces, eventHandle ) </span><span style="COLOR: #000000">===</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> ) {<br> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 标准事件。 这里绑定的为 eventHandle</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( elem.addEventListener ) {<br> elem.addEventListener( type, eventHandle, </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> );<br><br> } </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( elem.attachEvent ) {<br> elem.attachEvent( </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">on</span><span style="COLOR: #000000">"</span><s></s>
</div>
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
jquery实现多少秒后隐藏图片jquery实现多少秒后隐藏图片Apr 20, 2022 pm 05:33 PM

实现方法:1、用“$("img").delay(毫秒数).fadeOut()”语句,delay()设置延迟秒数;2、用“setTimeout(function(){ $("img").hide(); },毫秒值);”语句,通过定时器来延迟。

jquery怎么修改min-height样式jquery怎么修改min-height样式Apr 20, 2022 pm 12:19 PM

修改方法:1、用css()设置新样式,语法“$(元素).css("min-height","新值")”;2、用attr(),通过设置style属性来添加新样式,语法“$(元素).attr("style","min-height:新值")”。

axios与jquery的区别是什么axios与jquery的区别是什么Apr 20, 2022 pm 06:18 PM

区别:1、axios是一个异步请求框架,用于封装底层的XMLHttpRequest,而jquery是一个JavaScript库,只是顺便封装了dom操作;2、axios是基于承诺对象的,可以用承诺对象中的方法,而jquery不基于承诺对象。

jquery怎么在body中增加元素jquery怎么在body中增加元素Apr 22, 2022 am 11:13 AM

增加元素的方法:1、用append(),语法“$("body").append(新元素)”,可向body内部的末尾处增加元素;2、用prepend(),语法“$("body").prepend(新元素)”,可向body内部的开始处增加元素。

jquery中apply()方法怎么用jquery中apply()方法怎么用Apr 24, 2022 pm 05:35 PM

在jquery中,apply()方法用于改变this指向,使用另一个对象替换当前对象,是应用某一对象的一个方法,语法为“apply(thisobj,[argarray])”;参数argarray表示的是以数组的形式进行传递。

jquery怎么删除div内所有子元素jquery怎么删除div内所有子元素Apr 21, 2022 pm 07:08 PM

删除方法:1、用empty(),语法“$("div").empty();”,可删除所有子节点和内容;2、用children()和remove(),语法“$("div").children().remove();”,只删除子元素,不删除内容。

jquery怎么去掉只读属性jquery怎么去掉只读属性Apr 20, 2022 pm 07:55 PM

去掉方法:1、用“$(selector).removeAttr("readonly")”语句删除readonly属性;2、用“$(selector).attr("readonly",false)”将readonly属性的值设置为false。

jquery on()有几个参数jquery on()有几个参数Apr 21, 2022 am 11:29 AM

on()方法有4个参数:1、第一个参数不可省略,规定要从被选元素添加的一个或多个事件或命名空间;2、第二个参数可省略,规定元素的事件处理程序;3、第三个参数可省略,规定传递到函数的额外数据;4、第四个参数可省略,规定当事件发生时运行的函数。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。