querySelectorAll Bug 及 Jquery解决方法简析

本文探讨了querySelectorAll在复杂DOM结构中出现的匹配错误,并详细解析了Jquery如何通过添加唯一ID和修改选择器来修正这一问题,确保了更精确的选择器匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

querySelectorAll Bug 及 Jquery解决方法

<div id="try">
	<span>
		<p></p>
	</span>
</div>

如果用querySelectorAll来查找p标签:

  var demo = document.getElementById('try');
  console.log(demo.querySelectorAll('div span p'));
  console.log(demo.querySelectorAll('span p'));

两种都可以查到 p 标签。显然,这是不符合我们常用的规范的。
但是,如果在Jquery中查询(jquery中会优先使用querySelectorAll方法)会有什么结果呢?

  console.log($('div span p',demo));

找不到p标签,也是我们希望得到的结果,那Jquery是怎么实现的呢?下面代码是Jquery中sizzle函数中的片段。(我的jquery版本是2.0.3)。

			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
				groups = tokenize( selector );

				if ( (old = context.getAttribute("id")) ) {//如果上下文(即demo,下面统一简称demo)有id值
					nid = old.replace( rescape, "\\$&" );//把id值处理(处理编码,不用在意)后赋给nid
				} else {
					context.setAttribute( "id", nid );//如果demo没有id值,给他一个唯一的id值。
				}
				nid = "[id='" + nid + "'] ";  //造一个id的属性值形式的字符串(即内容为[ id = 'demo'] 的字符串)

				i = groups.length;
				while ( i-- ) { //循环给我们的选择器添加值(即   把'div span p' --->"[id = 'demo'] div span p")
					groups[i] = nid + toSelector( groups[i] );
				}
				newContext = rsibling.test( selector ) && context.parentNode || context;
				newSelector = groups.join(",");
			}

			if ( newSelector ) {
				try {
					push.apply( results,
						newContext.querySelectorAll( newSelector )//最后用querySelectorAll查找
					);
					return results;
				} catch(qsaError) {
				} finally {
					if ( !old ) {
						context.removeAttribute("id");
					}
				}
			}

总体上来讲,jquery实现修正的思想可以分为 3步:
1,先看上下文对象(demo)有没有id值,有就拿过来,没有就给他一个唯一的id值。
2,把id拿来,生成对应的属性字符串("[id = ‘demo’]"),在把字符串拼接到选择器前面(‘div span p’ ----> “[id = ‘demo’] div span p”)
3,直接使用querySelectorAll查找,这样就完成了jquery的修正。

以上是我个人见解,如果有不到位的地方,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值