jQuery从入门到精通(微课精编版)
上QQ阅读APP看书,第一时间看更新

2.4 jQuery构造函数

jQuery提供唯一的接口—jQuery()构造函数。jQuery把所有的功能和操作都包装在一个jQuery()构造函数中,它的核心功能都是通过这个函数实现的。jQuery中的一切都基于这个函数,或者说都是在以某种方式使用这个函数。

jQuery()构造函数能够接收任意类型的参数,但是能够正确解析的参数包括下面3种类型。

2.4.1 jQuery([selector,[context]])接口

jQuery()构造函数最基本的用法就是向它传递一个表达式,通常由CSS选择器组成,然后根据这个表达式来查找所有匹配的元素。接口用法如下:

     jQuery([selector,[context]])

参数说明:

 selector:可选参数,用来查找的表达式,如CSS选择器字符串。

 context:可选参数,作为待查找的DOM元素集、文档或jQuery对象。

提示:在默认情况下,如果没有指定context参数,jQuery()构造函数将在当前的HTML document中查找DOM元素;如果指定了context参数,如一个DOM元素集或jQuery对象,那么就会在这个context中查找。

在jQuery 1.3.2版本以后,jQuery()返回的元素顺序等同于在context中出现的先后顺序。

1.jQuery()

如果没有指定任何参数,则返回一个空的jQuery对象。例如:

【源码解析】

在jQuery源码中,可以看到init()初始化处理函数首先处理无参数的情况。

如果jQuery()参数为空,或者为空字符串、null、undefined、false等假值情况,将直接返回this原型对象,该对象不包含任何DOM元素,length属性为默认值0。

2.jQuery(string)

如果传入一个字符串,则可能需要处理的条件比较复杂。例如:

【源码解析】

在jQuery源码中,可以看到init()初始化处理函数的第2个条件包含如下代码。

该条件下的jQuery源码将在2.4.2节详细解析。

3.jQuery(element)

如果传入一个DOM元素,则返回一个包含该元素的jQuery对象。例如:

【源码解析】

在jQuery源码中,可以看到init()初始化处理函数的第3个条件包含如下代码。

4.jQuery(object)

如果传入一个Object对象,则返回一个包含该对象的jQuery对象,即将参数对象封装为jQuery。例如:

在Firefox浏览器中可以看到控制台输出的Object结构信息,如图2.4所示。

图2.4 显示jQuery对象结构1

注意:很少使用这种用法,用户不能在返回的jQuery对象上调用与DOM相关的操作方法,因为当前jQuery对象中包含的元素不是DOM元素,而是一个JavaScript对象。

5.jQuery(elementArray)

如果传入一个DOM元素集合,则返回一个包含所有DOM元素的jQuery对象,即将DOM元素集合封装为jQuery。

例如,在下面示例中,分别使用document.getElementsByTagName在文档中匹配所有p元素,或者使用document.createElement创建两个p元素,然后组成一个数组,最后使用jQuery()进行封装,则在控制台可以看到输出的jQurey对象,如图2.5所示。

     <p></p>
     <p></p>
     <script>
     var eles = document.getElementsByTagName("p");
     console.dir(jQuery(eles));
     </script>

或者

     var eles = [document.createElement("p"), document.createElement("p")];
     console.dir(jQuery(eles));

图2.5 显示jQuery对象结构2

6.jQuery(jQuery)

如果传入一个jQuery,则返回一个新的jQuery对象,这个对象是参数jQuery对象的复制品。

提示:一般通过这种方式复制一个jQuery对象。

【源码解析】

在jQuery源码中,可以看到init()初始化处理函数中使用jQuery.makeArray()函数来处理参数为Object、Arry和jQuery。

     init = jQuery.fn.init = function (selector, context, root) {
          …
          return jQuery.makeArray(selector, this);
     };

当参数为JavaScript对象、DOM集合或数组、jQuery对象时,将使用jQuery.makeArray()把它们封装为jQuery对象。

jQuery.makeArray()工具函数可以把类数组转换为数组,或者合并成两个类数组,其源码如下:

isArrayLike()函数可以判断一个对象是否为类数组,jQuery.merge()工具函数能够合并两个数组或类数组。由于代码比较简单,此处不再展开说明,详细代码可以搜索、参考本书提供的注释版jQuery源码文件。

2.4.2 jQuery(html,[ownerDocument])接口

该接口能够根据提供的原始HTML标记字符串,动态创建由jQuery对象包装的DOM元素,同时也可以设置一系列的属性、事件等。接口用法如下:

     jQuery(html,[ownerDocument] )
     jQuery(html,props )

参数说明如下:

 html:必设参数,用于动态创建DOM元素的HTML标记字符串。

 ownerDocument:可选参数,创建DOM元素所在的文档。

 props:可选参数,用于附加到新创建元素上的属性、事件和方法,以对象直接量(Map)的形式设置的配置参数。

【示例】下面示例动态创建一个p元素,并添加到body元素上,设置p元素的类名为red,包含文本为“变色文本”,为该元素绑定单击事件。当单击段落文本时,使用toggleClass()方法切换red类样式,实现类样式red的添加和移出不断切换。

【源码解析】

该接口的实现,主要是通过临时创建一个元素,并将这个元素的innerHTML属性设置为给定的HTML字符串,从而实现将HTML字符串转换为DOM元素数组。

这部分代码比较长,因为针对参数selector的字符串形式有多种,主要包括:

 CSS选择器字符串,如"div#box"。

 HTML字符串,如"<div>"。

 ID标识符,如"#box"。本来ID标识符也应该属于CSS选择器范畴,但是为了提高执行效率,jQuery把ID选择器提前进行解析,因为它比较简单,只要匹配出ID值,使用document.getElementById方法可以快速查找到。

对于CSS选择器字符串的处理,内部逻辑复杂,jQuery使用Sizzle选择器引擎模块专门对其进行解析,接口函数为find()。第3章将专门对Sizzle选择器引擎模块进行讲解。

HTML字符串的解析过程如下:

第1步,如果selector表达式为字符串,则进入init()处理函数的第2个条件内进行处理。

     if (typeof selector === "string") {  }

第2步,判断字符串是否为HTML标签,如果是单纯的标签,则不用正则表达式进行匹配;如果是复杂的HTML字符串片段,则使用正则表达式进行匹配。

第3步,对匹配结果match进行判断。如果匹配到标签,或者没有指定上下文,则考虑解析HTML字符串,或者使用document.getElementById方法找到指定ID元素。

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

第4步,在第3步条件内,进一步判断match[1]是否存在,如果匹配到标签,则进入HTML字符串解析流程。

第5步,在if (match[1]){ }条件中,先使用jQuery.parseHTML方法把HTML字符串解析为DOM元素数组,再使用jQuery.merg方法把它导入当前jQuery对象中。

     jQuery.merge(this, jQuery.parseHTML(
         match[1],//HTML字符串
         //如果context存在,且为DOM节点
         //如果存在context.ownerDocument,则使用它,否则使用context
         //如果没有指定context,则使用document
         context && context.nodeType ? context.ownerDocument || context : document,
         true     //设置第3个参数为true,表示允许解析script元素
       ));

第6步,检测HTML字符串是否为单个标签,且设置了第2个参数为对象直接量。

     if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { }

第7步,如果为单标签,且设置了配置参数对象,则在上一步条件语句内使用for语句映射配置对象到标签上,为其设置标签属性。

第8步,如果没有匹配到HTML标签,且没有设置上下文,则跳过HTML字符串解析,进入else分支,处理ID选择器。

2.4.3 jQuery(callback)接口

jQuery(callback)实际上是$(document).ready()的简写。该接口允许用户绑定一个在DOM文档载入完成后执行的函数。例如:

     $(function(){
           //文档就绪
     });

参数是一个处理函数。ready事件处理函数在文档内容完全载入之后立即执行,不需要等待外部链接的文件是否载入完成,因此响应要比load事件早。

【源码解析】

在jQuery源码中,可以看到init()初始化处理函数的第4个条件包含如下代码。