第三天主要对match的值做了一个判断 match[1]要么是标签字符串,要么macth就是null 像<li>、<li>11都转成'li'作为match[1]。
match[1]现在'<li><li>' 或 '<li>'
if (match && (match[1] || !context)) // 判断 id 是否有环境context限制,只有没有限制(不写默认document,这里的匹配就是不写第二个参数的情况) $('#box')
①满足match有值,即匹配rquickExpr , ② $('<li>')、$('<li>',document)、$('<li>',其他环境如iframe,第三方插件) ,match[1] || ! context 当match[1]存在就是标签,match[2]存在就是#aa的形式,因为如果if成立match确定存在,当match[2]存在然后满足context这个环境不存在即可(不存在即默认是在document也就是本文档中)
我所理解的context : 假如说我在本html页面的body里面添加了一个<div id="box">,那么$('#box'),可以获取,但是我不在当前html文件创建,我跑到其他html页面创建,然后通过iframe引进来,这时候$("#box",context),第二个参数context就起作用了(iframe用得不多,所以一般来说context不写默认document就好),同理在第三方插件中可能也有#box这个id元素。可以说jquery被大家这么广为流传不是没有原因的,兼顾到了不常用的情况,像iframe在H5都废弃了。
补充一下:需要了解正则表达式.exec()的朋友:http://www.w3school.com.cn/js/jsref_exec_regexp.asp
1 if (match[1]) { //创建标签 -- 2 context = context instanceof jQuery ? context[0] : context; 3 4 // scripts is true for back-compat 5 jQuery.merge( 6 this, 7 jQuery.parseHTML( 8 match[1], 9 context && context.nodeType? context.ownerDocument || context : document, 10 true 11 ) 12 );
if (match[1]) 不是‘#aa’,这种id的情况,是'<aaa>'这种情况尖括号开头结尾
context = context instanceof jQuery ? context[0] : context; // $('<li>',$(document))或 $('<li>',$('ul')) $(document)[0],原生document就是document,
那么jquery会从ul下面去找,说通俗点就是一个查找域,经过这行代码转变成原生节点,后续需要用到原生DOM对象这一性质,但这一代码并不能保证无意义的字符串$('li','uu'),uu在节点
上根本没有的情况这行代码不做判断因为context直接逻辑短路
// 插入script标签
jQuery.merge( this, jQuery.parseHTML( match[1], context && context.nodeType ? context.ownerDocument || context : document, true ) );
jQuery.parseHTML()的作用如下:var str = "<li>1</li><li>2</li><li>3</li>";jQuery.parseHTML(str) 返回的数组[li,li,li],每个li都是一个DOM原生对象。
接下来看一下三个参数,一个节点字符串,一个查找域,一个布尔值
match[1]:各种'< 里面可以是任意字符 >'类型
查找域 :context && context.nodeType ? context.ownerDocument || context : document 【此时context已是原生节点】【如果context不存在就是默认document】【如果存在并且是DOM节点的话,context可以是本身也可以是context.ownerDocument属性一样的思议】
布尔值:默认是false,true的话处理的是'<script></script>'标签插入的情况,这么写不行,如果前面有script标签,会认为配对所以要转义'<script><\/script>',然后就算这样加入到DOM节点还是起不到js效果,只有设置了true才会在DOM节点上起js效果。
然后看jQuery.merge(this,返回的节点数组):this指向jQuery构造函数的实例,将返回的节点数组和this合并要有length属性,需要和数组的length属性相加。 这样的结果就是this中新增了原生的节点,但是却是用原本对象的最后一个数字属性名(已经被对象的length截取之后)之后再去拼接的
简单说说: 如果obj1 = { '3' : '哈哈',length : 4} arr = [1,2,3] $.merge(obj1,arr) //代表的就是{ '3' : '哈哈','4':1, '5':2,'6':3,length : 7}
所以明白了为什么$()[0]可以拿到原生节点,因为改造了this这个jQuery构造函数的实例
下面是我另写的一篇关于$.merge()的:https://www.cnblogs.com/wchjdnh/p/10763451.html
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { //满足一对标签或单标签和 第二个参数是纯对象形式 $('<li></li>',{ title : '我是li' , html : 'hh',css:{color:'red'} }) for (match in context) { // 属性遍历context,这是对象遍历match不一定是数字字符串 // Properties of context are called as methods if possible if (jQuery.isFunction(this[match])) { //判断this[match]是不是方法 this[match](context[match]); //是方法就调用参数是context[match]的值 ,也就是说$('<li></li>',{ title : '我是li' , html : 'hh',css:{color:'red'} })中像html,css都是jQuery的方法,那就直接调用 // ...and otherwise set as attributes } else { this.attr(match, context[match]); //不是方法作为属性设置 title不是方法直接处理用设置属性的方式 } } }
return this; //创建标签结束,因为是创建标签操作,其他代码的操作不执行return,创建标签结束返回的是jQuery对象 比方说$('<li>1</li>').appendTo('ul')返回li的jQuery对象
// return this是结束创建标签节点的相关操作 同时return this就是返回工厂函数jQuery(这时候看成工厂函数)创造的this,这个this已经被改造成了有原生DOM节点的jQuery对象实例了