博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jQuery内核详解与实践读书笔记2:破解jQuery选择器接口1
阅读量:4332 次
发布时间:2019-06-06

本文共 5639 字,大约阅读时间需要 18 分钟。

前两篇已经介绍了如何搭建一个jQuery框架的雏形,从这一篇开始详细了解jQuery选择器的接口。jQuery选择器功能强大但用法很简单,它仅仅提供了一个接口:jQuery(),也可以简写为$()。

1. 简单但很复杂的黑洞

jQuery提供了唯一的接口(jQuery()或$())使选择器与外界进行交流。

jQuery框架的基础是查询,即查询文档元素对象,因此可以认为jQuery对象就是一个选择器,并在此基础上构建和运行查询过滤器。
jQuery查询结果的数据集合是jQuery对象的一部分。
在$()函数中可以包含选择字符串,HTML字符串,DOM对象和数据集合等不同类型的参数。jQuery是如何分辨这些参数呢?
为了方便理解其中的奥秘,把jQuery框架进行简化,先删除所有方法,函数以及逻辑代码,然后在init()构造器中,使用alert()方法获取selector参数的类型和信息,代码如下:

1 (function() { 2   var window = this; 3   jQuery = window.jQuery = window.$ = function(selector, context) { 4     return new jQuery.fn.init(selector, context); 5   }; 6   jQuery.fn = jQuery.prototype = { 7        init : function(selector, context) { 8          alert(selector); 9        }10   };11 })();12 window.onload = function() {13   $("div.red");//获取"div.red"14   $("div .red");//获取"div .red"15   $(document.getElementById("wrap"));//获取"[object HTMLDivElement]"16   $("#wrap", document.forms[0]);//获取"wrap"17   $("
hello, world
");//获取"
hello, world
"18 };

 

2. 盘根错节的逻辑关系

jQuery()的4种构建jQuery对象的方式:

  jQuery(expression, [context])

  jQuery(html, [ownerDocument])

  jQuery(elements)

  jQuery(callback)

jQuery对象的方法都是针对DOM元素对象进行的操作。

jQuery对象就是jQuery.fn.init构造器创建的对象,而通过jQuery.fn.init.prototype = jQuery.fn途径,再使用jQuery的原型对象去覆盖jQuery.fn的原型对象,使得jQuery对象的原型方法也就被继承过来,从而形成了错综复杂但又井然有序的关系。

 

3. jQuery构造器

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

从本质上讲,使用jQuery选择器(即jQuery.fn.init()构造器)构建jQuery对象,就是在this对象上附加DOM元素集合,附加的方式包括以下两种:
  1. 如果是单个DOM元素,可以直接把DOM元素作为数组元素传递给this对象,还可以通过ID从DOM文档中查询元素
  2. 如果是多个DOM元素,则以集合方式附加,如jQuery对象、数组和对象等,此时可以通过CSS选择器匹配到所有DOM元素,然后过滤,最后构建类数组的数据结构
其中,CSS选择器是通过jQuery().find(selector)函数来完成的。通过jQuery().find(selector)可以分析选择器字符串,并在DOM文档树中查找到符合语法的元素集合。

下面先来分析一下init()初始化构造器函数,来分析jQuery选择器是如何工作的。

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

代码中已经对相关的判断逻辑做了详细的说明,这里就不在做解释说明了。

今天就先写到这里,下一篇内容将是关于jQuery如何生成DOM元素和引用DOM元素。欢迎转载,转载请注明出处。

 

 

个人微信公众号:programmlife,如有兴趣敬请关注,主要内容是一个码农的所见所思所叹,或扫描下方二维码关注:

 

转载于:https://www.cnblogs.com/noah-wung/p/3997521.html

你可能感兴趣的文章
Hibernate视频学习笔记(8)Lazy策略
查看>>
CSS3 结构性伪类选择器(1)
查看>>
IOS 杂笔-14(被人遗忘的owner)
查看>>
自动测试用工具
查看>>
前端基础之BOM和DOM
查看>>
[T-ARA/筷子兄弟][Little Apple]
查看>>
编译Libgdiplus遇到的问题
查看>>
【NOIP 模拟赛】Evensgn 剪树枝 树形dp
查看>>
java学习笔记④MySql数据库--01/02 database table 数据的增删改
查看>>
两台电脑如何实现共享文件
查看>>
组合模式Composite
查看>>
程序员最想得到的十大证件,你最想得到哪个?
查看>>
我的第一篇CBBLOGS博客
查看>>
【MyBean调试笔记】接口的使用和清理
查看>>
07 js自定义函数
查看>>
jQueru中数据交换格式XML和JSON对比
查看>>
form表单序列化后的数据转json对象
查看>>
[PYTHON]一个简单的单元測试框架
查看>>
iOS开发网络篇—XML数据的解析
查看>>
[BZOJ4303]数列
查看>>