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选择器是如何工作的。为了方便解释,我们先结合源代码进行讲解。
广州网站建设,网站建设,广州网页设计,广州网站设计
- //jQuery原型对象
- //构造jQuery对象的入口
- //所有jQuery对象方法都通过jQuery原型对象来继承
- jQueryjQuery.fn = jQuery.prototype = {
- //jQuery对象初始化构造器,相当于jQuery对象的类型,由该函数负责创建jQuery对象
- 参数说明:selector:选择器的符号,可以是任意数据类型。考虑DOM元素操作需要,该参数应该是包含DOM元素
- 的任何数据
- context:上下文,指定在文档DOM中哪个节点下开始进行查询,默认值为document
- init: function( selector, context ) {
- selectorselector = selector || document; //确保selector参数存在,默认值为document
- //第一种情况,处理选择符为DOM元素,此时将忽略上下文,即忽略第二个参数
- //例如,$(document.getElementById("wrap")) , jQuery (DOMElement)匹配DOM元素。
- //先使用selector.nodeType判断当selector为元素节点,将length设置为1,
- //并且赋值给context,实际上context作为init的第二个参数,
- //也意味着它的上下文节点就是selector该点,返回它的$(DOMElement)对象
- if (selector.nodeType) { //存在nodeType属性,说明选择符是一个DOM元素
- this[0] = selector; //直接把当前参数的DOM元素存入类数组中
- this.length = 1; //设置类数组的长度,以方便遍历访问
- this.context = selector; //设置上下文属性
- return this; //返回jQuery对象,即类数组对象
- }
- //如果选择符参数为字符串,则进行处理
- //例如,$("<div>hello,world</div>"),jQuery (html,[ownerDocument])匹配HTML字符串
- if (typeof selector == "string") {
- //使用quickExpr正则表达式匹配该选择符字符串,决定是处理HTML字符串,还是处理ID字符串
- // quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/
- var match = quickExpr.exec(selector);
- // 验证匹配的信息,任何情况下都不是#id
- if (match && (match[1] || !context)) {
- //第二种情况,处理HTML字符串,类似$(html) -> $(array)
- if (match[1])
- selector = jQuery.clean([match[1]], context);
- //第三种情况,处理ID字符串,类似$("#id")
- else {
- var elem = document.getElementById (match[3]); //获取该元素确保元素存在
- 处理在 IE 和 Opera 浏览器下根据name,而不是ID返回元素
- if ( elem && elem.id != match[3] )
- return jQuery().find( selector ); // 默认调用document.find()方法
- // 否则将把elem作为元素参数直接调用jQuery()函数,返回jQuery对象
- var ret = jQuery( elem || [] );
- ret.context = document; // 设置jQuery对象的上下文属性
- ret.selector = selector; // 设置jQuery对象的上选择符属性
- return ret; // 返回jQuery对象
- }
- } else
- //第四种情况,处理jQuery(expression, [context]),
- //例如,$("div .red")的表达式字符串
- return jQuery( context ).find( selector );
- } else if ( jQuery.isFunction( selector ) )
- //第五种情况,处理jQuery(callback),即$ (document).ready()的简写
- //例如, $(function(){ alert("hello,world");}) ,
- //或者$(document).ready(function() { alert("hello,world");})
- return jQuery( document ).ready( selector );
- // 确保旧的选择符能够通过
- if ( selector.selector && selector.context ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
- // 第六种情况,处理类似$(elements)
- return this.setArray(jQuery.isArray( selector ) ?
- selector :
- jQuery.makeArray(selector));
- }
- //……
- }
广州网站建设,网站建设,广州网页设计,广州网站设计
进一步分析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对象。



