zoukankan      html  css  js  c++  java
  • Jquery源码分析

    1、概述                      

       jQuery是一个非常优秀的Js库,与prototype,YUI,Mootools等众多的Js类库相比,它剑走偏锋,从web开发最实用的角度出发,抛除了一些中看但不实用的东西,为开发者提供一个短小精悍的类库。由于其个短小精悍,使用简单方便,性能相对高效。众多的开发者都选择Jquery来进行辅助的web开发。

    在使用jquery时开发,我们也会时常碰到许多的问题,但是jquery的代码很晦涩,难起看懂,当开发时出现了问题,看不懂源码,不知道如何去排错。

    John Resig,Jquery的开发者,写了两本书,Pro Javascript Techniques 可以看作是对Jquery的源码分析。这个对于分析源码,从基本上去比较目前的类库都有很大的帮助。另外一本是jQuery.in.Action。这本主要是讲怎么去使用Jquery。二本书都深入浅出。还有一个由本手册由一揪整理编辑JqueryAPI的中文文档。这三个对于精通Jquery是有很大帮助的。

    2、init()分析

    在分析init()之前,我们得明白jQuery的设计理念。

    Jquery是站在开发者的角度去考虑问题,在使用Js的时候,大部分时间都是对Dom元素进行操作,比如修改元素的属性,修改内容,修改CSS等。但是取Dom元素的,如getElementsByTag,有可能会取到一些Dom元素的集合,而又正好要这个集合的所有的元素都要进行同样的操作。如果只有一个元素,完全可以看作只有一个元素的集合。

    这样只要对这个集合进行操作,就会对集合的每个元素都进行操作。jQuery就是基于这个集合而提供了众多的实用方法,包含了日常开发所需要的功能。对于这个集合,我们称为jquery对象。

    我们可以通过$(params)或jquery(params)来生成Jquery对象。在Jquery文档中提供了四种方式:jQuery(expression,[context]),jQuery(html),jQuery(elements),jQuery(callback)四种构寻jquery对象的方式。其实Jquery的参数可以是任何的元素,如空参数,都能构成jquery对象。

    那么jquery是如何实现的呢?

    ①②③④⑤⑥⑦⑧⑨⑩

    var jQuery = window.jQuery = window.$ = function(selector, context) {

        // The jQuery object is actually just the init constructor 'enhanced'

        return new jQuery.fn.init(selector, context);                       ①

    };

    可以看得出其实就是new init(selector, context):

    init : function(selector, context) {

           selector = selector || document;// 确定selector存在

           // 第一种情况 Handle $(DOMElement)单个Dom 元素,忽略上下文

           if (selector.nodeType) {                                            ②

               this[0] = selector;

               this.length = 1;

               return this;

           }     

           if (typeof selector == "string") {//selector为string           ③

               var match = quickExpr.exec(selector);        

               if (match && (match[1] || !context)) {

                  if (match[1])// 第二种情况处理$(html) -> $(array)         ④

                      selector = jQuery.clean([match[1]], context);

                  else {// 第三种情况:HANDLE: $("#id")//处理$("#id")

                      var elem = document.getElementById(match[3]);

                      if (elem) {                    

    // IE会返回name=id的元素 ,如果是这样,就document.find(s)

    if (elem.id != match[3])                        ⑤

                             return jQuery().find(selector);

                            // 构建一个新的jQuery(elem)

                         return jQuery(elem);                            ⑥

                      }

                      selector = [];

                  }

               } else                                                      

               // 第四种情况:处理$(expr, [context])==$(content).find(expr)

                  return jQuery(context).find(selector);               ⑦

           } else if (jQuery.isFunction(selector))                      ⑧   // 第五种情况:处理$(function)七Shortcut for document ready       

    return jQuery(document)[jQuery.fn.ready ? "ready" : "load"](selector);

    // 第六种情况:处理$(elements)

    return this.setArray(jQuery.makeArray(selector));                   ⑨

        },

    上面的代码①可以看出$(xx)或Jquery(xx)得到不是真正的jQuery函数生成的对象,而是jQuery.fn.init函数生成的对象。也是就是jQuery的对象继承的是jQuery.fn.init的原型。jQuery.fn = jQuery.prototype={..}。我们基本上不用new jQuery(xx),而是直接jQuery(xx),就是采用了new jQuery(xx),先生成jQuery函数的对象,把原型中的继承下来,返回的也是jQuery.fn.init函数生成的对象。而jQuery函数的对象也抛弃了。可见给jQuery.prototype上增加方法的意义不大。同时也可以看出采用new jQuery(xx)的效率更低。jQuery.fn.init是通过jQuery.fn.init.prototype = jQuery.fn;来获得的。在扩展jQuery的时候,只要把相关的函数extend到jQuery.fn就可以了。

    jQuery.fn.init负责对传的参数进行分析然后生成jQuery对象。它把第一个参数分成四种情况:

    类型

    说明

    Dom Element

    第一个参数为Dom元素,第二个参数不用。直接把Dom元素存在新生成的jQuery对象的集合中。返回这个jQuery对象。构建jQuery对象完成。

    string

    第一个参数为string有三种情况:

     1、html的标签字符串,$(html) -> $(array),第二个参数可选。

          执行selector = jQuery.clean([match[1]], context);。该语句是把hteml的字符串转换成dom对象的数组。接着执行Array类型的返回。

    2、字符串为#id时$(id)

       首先通过var elem = document.getElementById(match[3]);取得elem,如没有取到selector = [];转到执行Array类型的返回空集合jquery对象。

     如找到elem,通过return jQuery(elem);再次生成jquery对象,这次是

    Dom Element类型的jquery对象的返回。

    3、兼容css1-3语法的selector字符串,第二个参数是可选的。

          执行return jQuery(context).find(selector);。该语句先执行jQuery(context)。可以看出context第二参数可以是任意的值,可以是集合形式。之后就通过find(selector)找到jQuery(context)中所有dom元素都满足selector表达式的dom元素的集合,构建新的jquery对象,并返回。

         #id其实和这种方式是统一的,单独出来是为了提高性能。

    Fn

    第一参数是函数。第二个参数不用。是$(document).ready(fn)的的简写,其returnjQuery(document)[jQuery.fn.ready ? "ready" : "load"](selector)是其执行的代码。这个语句首先执行jQuery(document),它再一次newjQuery.fn.init函数,生成jQuery对象(元素为docume

     
  • 相关阅读:
    统计nginx日志里访问次数最多的前十个IP
    while 格式化输出 运算符 字符编码
    Python 软件安装
    Python 基础
    Typora 基础的使用方法
    Django ORM (四) annotate,F,Q 查询
    Django 惰性机制
    Django ORM (三) 查询,删除,更新操作
    Django ORM (二) 增加操作
    Django ORM (一) 创建数据库和模型常用的字段类型参数及Field 重要参数介绍
  • 原文地址:https://www.cnblogs.com/ranran/p/3754981.html
Copyright © 2011-2022 走看看