![jQuery从入门到精通(微课精编版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/735/26542735/b_26542735.jpg)
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对象。例如:
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P49_40507.jpg?sign=1738914467-eQY3RvUv2SIQo672otrS5JGVSN0y81R5-0-45881fbf53b6d58b359926556e2cb63f)
【源码解析】
在jQuery源码中,可以看到init()初始化处理函数首先处理无参数的情况。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P50_40508.jpg?sign=1738914467-3sV5kQm736BFTzJZewTB5vEbTL1FWuqw-0-c6361031d876342a7a12e122a63c3af0)
如果jQuery()参数为空,或者为空字符串、null、undefined、false等假值情况,将直接返回this原型对象,该对象不包含任何DOM元素,length属性为默认值0。
2.jQuery(string)
如果传入一个字符串,则可能需要处理的条件比较复杂。例如:
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P50_40509.jpg?sign=1738914467-dWzqTOys0QKv3ipi4EK9GA4K48Xdm3G0-0-881e725a37fc4040731936d6105b015d)
【源码解析】
在jQuery源码中,可以看到init()初始化处理函数的第2个条件包含如下代码。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P50_40510.jpg?sign=1738914467-e5pLTfVD1y5NAmnNseeE1nM05kPRPfEB-0-984b4dd1df94a847b112c05035201b36)
该条件下的jQuery源码将在2.4.2节详细解析。
3.jQuery(element)
如果传入一个DOM元素,则返回一个包含该元素的jQuery对象。例如:
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P50_40512.jpg?sign=1738914467-tEWw5IBqWR9Zinni5YrD5OfA9Jf2UbM0-0-dbc2b8ca5bd1c5ca6e8d180106cdf8b4)
或
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P50_40513.jpg?sign=1738914467-9F5bSaiCE2TxZDsYNygheyRK3xwGjZiY-0-729424c4f67b9564594bef84a287287e)
【源码解析】
在jQuery源码中,可以看到init()初始化处理函数的第3个条件包含如下代码。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P50_11056.jpg?sign=1738914467-8bicqJxTZALNHmyvBifvo3I2mz2Cig5D-0-ad491e1578d6ea9fe34e9855c28b92b2)
4.jQuery(object)
如果传入一个Object对象,则返回一个包含该对象的jQuery对象,即将参数对象封装为jQuery。例如:
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P51_40514.jpg?sign=1738914467-qk7JEZIOTZhYzCPmKclHz0o8HJHa0p8G-0-6388c2f93acc110416f73c070da0f175)
在Firefox浏览器中可以看到控制台输出的Object结构信息,如图2.4所示。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P51_11095.jpg?sign=1738914467-ACDEhX3cGKVUIwo5vSp9PLh1BKzOWspB-0-51bfc0ea447b8b0ed7c0a0d465e04db4)
图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));
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P51_11108.jpg?sign=1738914467-oB9yZkkVs8Yax3G4kSpTw4vrFbrqukpn-0-fb83fa160fb4df02f93db6077bdea242)
图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()工具函数可以把类数组转换为数组,或者合并成两个类数组,其源码如下:
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P52_40515.jpg?sign=1738914467-BBEEAjc54oAeMZ237pXHxGKtStwHqeAj-0-5e608d9c95b06007dfde683293df1cf0)
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的添加和移出不断切换。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P53_40517.jpg?sign=1738914467-9gbpg2tv2JC6uyTvdk5gjnryj2oAtRpg-0-560876a0656bc66286f466cb56395d34)
【源码解析】
该接口的实现,主要是通过临时创建一个元素,并将这个元素的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选择器引擎模块进行讲解。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P53_40518.jpg?sign=1738914467-kePuqQOmWv5R24D3yWPtJSDbu6Uj9ppY-0-14e460ae6476d00a909ca3075b2466e2)
HTML字符串的解析过程如下:
第1步,如果selector表达式为字符串,则进入init()处理函数的第2个条件内进行处理。
if (typeof selector === "string") { }
第2步,判断字符串是否为HTML标签,如果是单纯的标签,则不用正则表达式进行匹配;如果是复杂的HTML字符串片段,则使用正则表达式进行匹配。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P53_40558.jpg?sign=1738914467-hXWorD98qXYtet8Bn6tVewE6Tn8tPRbo-0-e57459c4b06c4961569f219ecba29bff)
第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语句映射配置对象到标签上,为其设置标签属性。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P54_40521.jpg?sign=1738914467-jcIJkBilxIXttsmQnHuaqIFeztvxlJTB-0-bbb630eb86a07d5571909f6bb0a17248)
第8步,如果没有匹配到HTML标签,且没有设置上下文,则跳过HTML字符串解析,进入else分支,处理ID选择器。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P54_40566.jpg?sign=1738914467-5WaQxeTtc3eovxTgIQQIPXszGNGquMNk-0-523e4f61af5c75d7fa48cb1dbc41faab)
2.4.3 jQuery(callback)接口
jQuery(callback)实际上是$(document).ready()的简写。该接口允许用户绑定一个在DOM文档载入完成后执行的函数。例如:
$(function(){ //文档就绪 });
参数是一个处理函数。ready事件处理函数在文档内容完全载入之后立即执行,不需要等待外部链接的文件是否载入完成,因此响应要比load事件早。
【源码解析】
在jQuery源码中,可以看到init()初始化处理函数的第4个条件包含如下代码。
![](https://epubservercos.yuewen.com/A91516/15056702905210506/epubprivate/OEBPS/Images/Figure-P55_40524.jpg?sign=1738914467-CnwEn9JjaA1xBuar90npYnG79FUESvyA-0-8ca47a50edd49ba9c4fcbbb93ee3dcf8)