0 Comments

jQuery构造器

发布于:2013-05-31  |   作者:广州网站建设  |   已聚集:人围观
jQuery构造器

jQuery.fn.init()负责对传入参数进行分析,然后生成并返回jQuery对象。jQuery.fn.init()构造器的第一个参数是必须的,如果为空,则默认为document。

从本质上讲,使用jQuery选择器(即jQuery.fn.init()构造器)构建jQuery对象,就是在this对象上附加DOM元素集合。附加的方式包括以下两类。

如果是单个DOM元素,可以直接把DOM元素作为数组元素传递给this对象,还可以通过ID从DOM文档中查询元素。

如果是多个DOM元素,则以集合形式附加,如jQuery对象、数组和对象等,此时可以通过CSS选择器匹配到所有DOM元素,然后过滤,最后构建类数组的数据结构。

而CSS选择器,则是通过jQuery().find(selector)函数来完成的。通过jQuery().find (selector)可以分析选择器字符串,并在DOM文档树中查找到符合语法的元素集合。这个函数我们将在下面章节进行分析。该函数能够兼容CSS1~CSS3选择器。

下面就从init()初始化构造器函数开始,来分析jQuery选择器是如何工作的。为了方便解释,我们先结合源代码进行讲解。

广州网站建设,网站建设,广州网页设计,广州网站设计
  1. //jQuery原型对象  
  2. //构造jQuery对象的入口  
  3. //所有jQuery对象方法都通过jQuery原型对象来继承  
  4. jQueryjQuery.fn = jQuery.prototype = {  
  5.     //jQuery对象初始化构造器,相当于jQuery对象的类型,由该函数负责创建jQuery对象  
  6. 参数说明:selector:选择器的符号,可以是任意数据类型。考虑DOM元素操作需要,该参数应该是包含DOM元素  
  7.     的任何数据  
  8.     context:上下文,指定在文档DOM中哪个节点下开始进行查询,默认值为document  
  9.     init: function( selector, context ) {  
  10.         selectorselector = selector || document;   //确保selector参数存在,默认值为document  
  11.         //第一种情况,处理选择符为DOM元素,此时将忽略上下文,即忽略第二个参数  
  12.         //例如,$(document.getElementById("wrap")) , jQuery (DOMElement)匹配DOM元素。  
  13.         //先使用selector.nodeType判断当selector为元素节点,将length设置为1,  
  14.         //并且赋值给context,实际上context作为init的第二个参数,  
  15.         //也意味着它的上下文节点就是selector该点,返回它的$(DOMElement)对象  
  16.         if (selector.nodeType) {    //存在nodeType属性,说明选择符是一个DOM元素  
  17.             this[0] = selector;    //直接把当前参数的DOM元素存入类数组中  
  18.             this.length = 1;     //设置类数组的长度,以方便遍历访问  
  19.             this.context = selector;    //设置上下文属性  
  20.             return this;    //返回jQuery对象,即类数组对象  
  21.         }  
  22.         //如果选择符参数为字符串,则进行处理  
  23.        //例如,$("<div>hello,world</div>"),jQuery (html,[ownerDocument])匹配HTML字符串  
  24.         if (typeof selector == "string") {  
  25.             //使用quickExpr正则表达式匹配该选择符字符串,决定是处理HTML字符串,还是处理ID字符串  
  26.             // quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/  
  27.             var match = quickExpr.exec(selector);  
  28.             // 验证匹配的信息,任何情况下都不是#id  
  29.             if (match && (match[1] || !context)) {  
  30.                 //第二种情况,处理HTML字符串,类似$(html) -> $(array)  
  31.                 if (match[1])  
  32.                     selector = jQuery.clean([match[1]], context);  
  33.                 //第三种情况,处理ID字符串,类似$("#id")  
  34.                 else {  
  35.                     var elem = document.getElementById (match[3]); //获取该元素确保元素存在  
  36.                     处理在 IE 和 Opera 浏览器下根据name,而不是ID返回元素  
  37.                     if ( elem && elem.id != match[3] )  
  38.                         return jQuery().find( selector ); // 默认调用document.find()方法  
  39.                     // 否则将把elem作为元素参数直接调用jQuery()函数,返回jQuery对象  
  40.                     var ret = jQuery( elem || [] );  
  41.                     ret.context = document;    //  设置jQuery对象的上下文属性  
  42.                     ret.selector = selector;     //  设置jQuery对象的上选择符属性  
  43.                     return ret;     // 返回jQuery对象  
  44.                 }  
  45.             } else  
  46.                 //第四种情况,处理jQuery(expression, [context]),  
  47.                 //例如,$("div .red")的表达式字符串  
  48.                 return jQuery( context ).find( selector );  
  49.         } else if ( jQuery.isFunction( selector ) )  
  50.             //第五种情况,处理jQuery(callback),即$ (document).ready()的简写  
  51.             //例如, $(function(){ alert("hello,world");}) ,  
  52.             //或者$(document).ready(function() { alert("hello,world");})  
  53.             return jQuery( document ).ready( selector );  
  54.            // 确保旧的选择符能够通过  
  55.         if ( selector.selector && selector.context ) {  
  56.             this.selector = selector.selector;  
  57.             this.context = selector.context;  
  58.         }  
  59.         // 第六种情况,处理类似$(elements)  
  60.         return this.setArray(jQuery.isArray( selector ) ?  
  61.             selector :  
  62.             jQuery.makeArray(selector));  
  63.     }  
  64. //……  

广州网站建设,网站建设,广州网页设计,广州网站设计

进一步分析init()构造器函数的设计思路如下。

(1) 第一步,当第一个参数为DOM元素,则废除第二个参数,直接把DOM元素存储到jQuery对象的集合中,返回该jQuery对象。

(2) 第二步,如果第一个参数是字符串,则可能存在三种情况。

情况一,第一个参数是HTML标签字符串,第二个参数可选,则执行selector = jQuery.clean([match[1]], context);,该语句能够把HTML字符串转换成DOM对象的数组,然后执行Array类型数组并返回jQuery对象。

情况二,第一个参数是#id字符串,即类似$(id),则先使用document.getElementById()方法获取该元素,如果没有获得元素,则设置selector = [],转到执行Array类型,并返回空集合的jQuery对象。如果获得元素,则构建jQuery对象并返回。这里,把#id单独列出,是为了提高性能。

情况三,处理复杂的CSS选择符字符串,第二个参数是可选的。通过return jQuery().find( selector );语句实现。该语句先执行jQuery(context),可以看出第二参数context可以是任意值,也可以是集合数据。然后调用find(selector)找到jQuery (context)上下文中所有的DOM元素,即这些元素都满足selector表达式,最后构建jQuery对象并返回。

(3) 第三步,如果第一个参数是函数,则第二个参数可选。它是$(document).ready(fn)形式的简写,return jQuery(document)[jQuery.fn.ready ? "ready" : "load"](selector)是其执行的代码。该语句先执行jQuery(document),再通过new jQuery.fn.init()方式创建jQuery对象,此时元素为document。再调用这个对象的ready()方法,并返回当前的jQuery对象。

$(document).ready(fn)是实现domReady的jQuery对象的统一入口,可以通过$(fn)注册domReady的监听函数。所有的调用jQuery实现功能的代码都应该在domReady之后才能够运行。$(fn)是所有应用开发中的功能代码的入口,它支持任意多的$(fn)注册。

(4) 第四步,如果第一个参数是除DOM元素、函数和字符串之外的所有其他类型,也可以为空(如$()),而第二个参数可选。调用return this.setArray(jQuery.makeArray(selector));进行处理时,它先是把第一个参数转换为数组。当然这个参数可以是类数组结构的集合,如jQuery对象、getElementsByTag返回的DOM元素集合等,可支持$(this)。selector还可能是单个任意对象,转换成标准的数组之后,执行this.setArray把这个数组中的元素全部存储到当前的jQuery对象集合中,并返回jQuery对象。

标签:
飞机