一、源码思路分析总结 概要:
jQuery的核心思想可以简单概括为“查询和操作dom”,今天主要是分析一下jQuery.prototype.init选择器构造函数,处理选择器函数中的参数;
这个函数的参数就是jQuery()===$()执行函数中的参数,可以先看我之前写的浅析jQuery基础框架一文,了解基础框架后,再看此文。
思路分析:
以下是几种jQuery的使用情况(用于查询dom),每种情况都返回一个选择器实例(习惯称jQuery对象(一个nodeList对象),该对象包含查询的dom节点):
1、处理 $(""), $(null), $(undefined), $(false)
如果参数为以上非法值,jQuery对象不包含dom节点
2、处理 $(DOMElement)
如果参数为节点元素,jQuery对象包含该参数节点元素,并分别增加属性值为参数节点元素、1的context、length属性和用[]访问jQuery对象中dom节点的用法
例2.1:
复制代码 代码如下:
var obj = document.getElementById('container'),
jq = $(obj);
console.log(jq.length); //1
console.log(jq.context); //obj
console.log(jq.[0]); //obj
3、处理$(HTML字符串)
如果第一个参数为HTML字符串,jQuery对象包含由jQuery.clean函数创建的fragment文档碎片中的childnodes节点
例3.1:
复制代码 代码如下:
var jqHTML = $('<h1>文章标题</h1><p>内容</p>');
console.log(jqHTML); //[<h1>,<p>];
如果第一个参数(HTML字符串)为一个空的单标签,且第二个参数context为一个非空纯对象
例3.2:
复制代码 代码如下:
var jqHTML = $('<div></div>', { class: 'css-class', data-name: 'data-val' });
console.log(jqHTML.attr['class']); //css-class
console.log(jqHTML.attr['data-name']); //data-val
4、处理$(#id)
如果第一个参数是一个#加元素id,jQuery对象包含唯一拥有该id的元素节点,
并分别增加属性值为document、参数字符串、1、的context、selector、length属性和用[]访问jQuery对象中dom节点的用法
例4.1:
复制代码 代码如下:
var jq = $('#container');
console.log(jq.[0]); //包含的dom节点元素
console.log(jq.length); //1
console.log(jq.context); //document
console.log(jq.selector); //container
5、处理$(.className)
如果第一个参数是一个.className,jQuery对象中拥有class名为className的标签元素,并增加一个属性值为参数字符串、document的selector、context属性
实际执行代码为:
复制代码 代码如下:
return jQuery(document).find(className);
6、处理$(.className, context)
如果第一个参数是.className,第二个参数是一个上下文对象(可以是.className(等同于处理$(.className .className)),jQuery对象或dom节点),
jQuery对象包含第二个参数上下文对象中拥有class名为className的后代节点元素,并增加一个context和selector属性
实际执行代码为:
复制代码 代码如下:
return jQuery(context).find(className);
例6.1:
html代码:
复制代码 代码如下:
<div class="main">
<h2 class="title">主内容标题</h2>
<p>主标题</p>
</div>
<div class="sub">
<h2 class="title">次内容标题</h2>
<p>次标题</p>
</div>
JavaScript代码:
复制代码 代码如下:
var jq, context;
context = '.sub';
var jq = $('.title', context);
console.log(jq.text()); //次内容标题
console.log(jq.context); //document
console.log(jq.selector); //.sub .title
context = $('.sub');
var jq = $('.title', context);
console.log(jq.text()); //次内容标题
console.log(jq.context); //document
console.log(jq.selector); //.sub .title
context = $('.sub')[0];
var jq = $('.title', context);
console.log(jq.text()); //次内容标题
console.log(jq.context); //className为sub的节点元素
console.log(jq.selector); //.title
7、处理$(fn)
如果第一个参数是fn函数,则调用$(document).ready(fn);
例7.1:
复制代码 代码如下:
$(function(e){
console.log('DOMContent is loaded');
})
//上面代码等同于:
jQuery(document).ready(function(e) {
console.log('DOMContent is loaded');
});
8、处理$(jQuery对象)
如果第一个参数是jQuery对象,上面已经分析过如果在查询dom时,参数是一个#加元素id,返回的jQuery对象会增加一个属性值为参数字符串、document的selector、context属性
例8.1:
复制代码 代码如下:
var jq = $('#container');
console.log(jq.selector); // #container
console.log(jq.context); // document
那么当出现$($('#container'))该如何处理呢?同样的,返回的jQuery对象同情况5和6处理的情况一样
例8.2:
复制代码 代码如下:
var jq2 = $($('#container'));
console.log(jq2.selector); // #container
console.log(jq2.context); // document
二、源码注释分析 [ 基于jQuery1.8.3 ]
复制代码 代码如下:
var rootjQuery = $(document),
rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
jQuery.fn = jQuery.prototype = {
init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc;
// Handle $(""), $(null), $(undefined), $(false)
if ( !selector ) {
return this;
}
// Handle $(DOMElement)
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
// Handle HTML strings
if ( typeof selector === "string" ) {
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
} else {
match = rquickExpr.exec( selector );
}
// Match html or make sure no context is specified for #id
// match[1]不为null,则为html字符串,match[2]不为null,则为元素id
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
doc = ( context && context.nodeType ? context.ownerDocument || context : document );
// scripts is true for back-compat
// selector是由文档碎片中的childnodes组成的数组
selector = jQuery.parseHTML( match[1], doc, true );
// 如果match[1]为空的单标签元素(如:<div><div>)且context为对象字面量
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
// 如果context对象不为空,则将对象中的属性添加到selector数组中仅有的dom节点中
this.attr.call( selector, context, true );
}
// merge函数的参数应该为两个数组,目的是将第二个数组中的项合并到第一个数组,而this并不是一个数组,
// this是选择器init构造函数的实例对象,该对象继承jQuery.prototype对象中的length属性(默认为0),因此可以理解好merge函数源码
// 将selector中的dom项合并到this对象中,并返回该对象
return jQuery.merge( this, selector );
// HANDLE: $(#id)
} else {
elem = document.getElementById( match[2] );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// by name instead of ID
// ie6,7和Opera存在此bug,当一个标签name和一个标签id值相等时,
// document.getElementById(#id)函数将返回提前出现的标签元素
if ( elem.id !== match[2] ) {
// 如果存在以上Bug,则返回由find函数返回的document文档的后代元素集合
return rootjQuery.find( selector );
}
// Otherwise, we inject the element directly into the jQuery object
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
// HANDLE: $(expr, $(...))
// context不存在或者context为jQuery对象
} else if ( !context || context.jquery ) {
return ( context || rootjQuery ).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
// context为className或者dom节点元素
} else {
// 等同于jQuery(context).find(selector)
return this.constructor( context ).find( selector );
}
// 处理$(fn)===$(document).ready(fn)
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
// 处理$(jQuery对象)
if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}
// 当第一个参数selector为jQuery对象时,将selector中的dom节点合并到this对象中,并返回this对象
return jQuery.makeArray( selector, this );
}
}
相关推荐:
SEO优化是做什么的?让你的网站流量飙升的秘密武器,乳腺癌ai作用机理
SEO人工优化-让你的网页轻松登上搜索引擎首页,ai主母
自动写文章的AI,提升效率的创作利器
人工AI软件的未来:智能时代的创新驱动力
为什么“360收录”是你网站推广的必备利器,seo亚马逊
SEO优化需要花钱吗?从零起步,如何让SEO成为企业的“隐形财富”,字体如何往ai里面倒
pbootcms自动翻译插件,让你的网站轻松实现多语言覆盖,ai 镀金
seo给你什么帮助,seo的利与弊 ,ai 大厨
seo渠道优化是什么,seo渠道推广怎么做 ,ai121333
揭开“好的AI软件”背后的秘密:让生活和工作更智能的利器
《*采集站:带你领略全球最全*资源的宝藏平台》,seo优化易下拉瞧瞧
ChatGPT可以实现新闻报道的即时自动化生成,怎么更改ai2的图标
ChatGPT不能打开EL?揭秘这一困扰背后的真相与解决方案,ai被动房
ChatGPT网页版内容显示不全的解决方案:如何轻松解决问题?,课件ai
SEO和品牌营销:如何通过搜索引擎优化打造品牌影响力,建邺seo软件
摘要AI生成:高效工作的新时代利器
优化分析:提升企业效益的关键策略,山东大网站建设
ChatGPT出现报错503?这些解决办法你必须知道!,粉墨ai说唱
颠覆写作方式:免费的AI续写软件助你轻松创作
seo涉及什么内容,seo主要包括 ,法医使用ai
SEO在广告领域的深度解析:如何利用SEO提升广告效果,网文写作ai工具
SEO找词:如何精准找到高效关键词,提升排名和流量,河源网站优化平台
撰写稿子的AI,写作的“超级助手”来了!
SEO桔子:提升网站排名的必备法宝,seo外包销售
ChatGPT翻译打不开?解决方法!,ai爱股票
ChatGPT支付时银行卡被拒绝?教你几招轻松解决问题!,国内ai换图
交友群都有哪些,交友群是干什么的 ,ai猫csgo
专业关键词助力SEO优化,让你的内容脱颖而出,东营响应式网站优化
互联网资源的无限潜力:如何利用数字世界为个人和企业创造价值,信阳网站建设正规公司
ChatGPT免登录:轻松畅聊,无需注册,快速体验AI智能助手,眼泪ai
ChatGPT免费版每天提问有次数限制吗?揭秘如何高效使用AI助手!,机甲ai手绘
AI上的文章属于原创吗?人工智能创作内容的归属问题
AI人物生成:重新定义虚拟形象创作的未来
为什么网站要做seo,网站做seo的目的是什么 ,ai初选
智能AI写作生成:如何借助人工智能提升创作效率与质量
SEO排位:如何通过精准策略提升网站排名,获得流量与转化,林海网络推广营销
ChatGPT内部HTTP接口文档-为开发者提供高效便捷的AI服务接入方式,安屿ai
为什么选择收录网站是企业在线营销的必备策略,全网营销与推广
AI生成文章免费工具,让创作变得轻松又高效,ai安心健
SEO利用:让你的网站快速登顶,获取更多流量与客户!,延边小程序推广平台网站
怎么用AI生成文章?全新写作方式的揭秘与应用指南
seo网站是什么找行者SEO,seo分析网站 ,ai图文梅花
seo网站页面优化包括什么,seo页面优化技术 ,no ai写作
为什么seo对企业重要,seo对企业进行网络营销的价值 ,ai李沁换脸鲍鱼
怎么用AI润色文章,让你的文稿瞬间高大上
SEO阶段解析:从入门到精通,助你站稳搜索引擎的前沿,网站建设特定开发
ChatGPTDNS出问题?如何快速解决并保障网络畅通,墨镜ai照片
SEO埋词技巧,如何提升网站排名?,贵州营销推广方法
SEO做网站点击:提升网站流量的关键策略,国内ai写作论文
ChatGPT+维护页面:您的智能助手之旅,安全、高效、无忧,奥特曼画图ai