再谈querySelector和querySelectorAll的区别与联系


Posted in Javascript onApril 20, 2012

先按W3C的规范来说这两个方法应该返回的内容吧:
querySelector:

return the first matching Element node within the node's subtrees. If there is no such node, the method must return null.(返回指定元素节点的子树中匹配selector的集合中的第一个,如果没有匹配,返回null)

querySelectorAll:

return a NodeList containing all of the matching Element nodes within the node's subtrees, in document order. If there are no such nodes, the method must return an empty NodeList. (返回指定元素节点的子树中匹配selector的节点集合,采用的是深度优先预查找;如果没有匹配的,这个方法返回空集合)

使用方法:

var element = baseElement.querySelector(selectors); 
var elementList = baseElement.querySelectorAll(selectors);

这在BaseElement 为document的时候,没有什么问题,各浏览器的实现基本一致;但是,当BaseElement 为一个普通的dom Node的时候(支持这两个方法的dom Node),浏览器的实现就有点奇怪了,举个例子:
<div class="test" id="testId"> 
<p><span>Test</span></p> 
</div> 
<script type="text/javascript"> 
var testElement= document.getElementById('testId'); 
var element = testElement.querySelector('.test span'); 
var elementList = document.querySelectorAll('.test span'); 
console.log(element); // <span>Test</span> 
console.log(elementList); // 1 
</script>

按照W3C的来理解,这个例子应该返回:element:null;elementList:[];因为作为baseElement的 testElement里面根本没有符合selectors的匹配子节点;但浏览器却好像无视了baseElement,只在乎selectors,也就是说此时baseElement近乎document;这和我们的预期结果不合,也许随着浏览器的不断升级,这个问题会得到统一口径!
人的智慧总是无穷的,Andrew Dupont发明了一种方法暂时修正了这个怪问题,就是在selectors前面指定baseElement的id,限制匹配的范围;这个方法被广泛的应用在各大流行框架中;
Jquery的实现:
var oldContext = context, 
old = context.getAttribute( "id" ),<BR> nid = old || id, 
try { 
if ( !relativeHierarchySelector || hasParent ) { 
return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); 
} 
} catch(pseudoError) {} <BR>finally { 
if ( !old ) {oldContext.removeAttribute( "id" );} 
}

先不看这点代码中其他的地方,只看他如何实现这个方法的;这点代码是JQuery1.6的片段;当baseElement没有ID的时候,给他设置一个id = "__sizzle__”,然后再使用的时候加在selectors的前面,做到范围限制;context.querySelectorAll( "[id='" + nid + "'] " + query ;最后,因为这个ID本身不是baseElement应该有的,所以,还需要移除:oldContext.removeAttribute( "id" );
,Mootools的实现:
var currentId = _context.getAttribute('id'), slickid = 'slickid__'; 
_context.setAttribute('id', slickid); 
_expression = '#' + slickid + ' ' + _expression; 
context = _context.parentNode;

Mootools和Jquery类似:只不过slickid = 'slickid__';其实意义是一样的;

方法兼容性:FF3.5+/IE8+/Chrome 1+/opera 10+/Safari 3.2+;

IE 8 :不支持baseElement为object;

非常感谢大牛JK的回复,提供了另外一种方法。

Javascript 相关文章推荐
Javascript 面向对象之重载
May 04 Javascript
兼容主流浏览器的JS复制内容到剪贴板
Dec 12 Javascript
JS判断字符串包含的方法
May 05 Javascript
js判断日期时间有效性的方法
Oct 24 Javascript
JS实现在状态栏显示打字效果完整实例
Nov 02 Javascript
基于Javascript实现弹出页面效果
Jan 01 Javascript
JS+html5 canvas实现的简单绘制折线图效果示例
Mar 13 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
Feb 06 Javascript
Vue组件中prop属性使用说明实例代码详解
May 31 Javascript
Vue中使用ElementUI使用第三方图标库iconfont的示例
Oct 11 Javascript
Vue组件通信入门之Provide和Inject机制
Dec 29 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
Mar 03 Javascript
js querySelector和getElementById通过id获取元素的区别
Apr 20 #Javascript
仿微博字符限制效果实现代码
Apr 20 #Javascript
javascript 另一种图片滚动切换效果思路
Apr 20 #Javascript
分享一个自定义的console类 让你不再纠结JS中的调试代码的兼容
Apr 20 #Javascript
浏览器解析js生成的html出现样式问题的解决方法
Apr 16 #Javascript
基于jquery的不规则矩形的排列实现代码
Apr 16 #Javascript
JavaScript打开word文档的实现代码(c#)
Apr 16 #Javascript
You might like
php生成图片缩略图的方法
2015/04/07 PHP
php app支付宝回调(异步通知)详解
2018/07/25 PHP
Laravel框架Auth用户认证操作实例分析
2019/09/29 PHP
JQuery 学习技巧总结
2010/05/21 Javascript
浅析document.createDocumentFragment()与js效率
2013/07/08 Javascript
JavaScript将页面表格导出为Excel的具体实现
2013/12/27 Javascript
BootStrap Validator对于隐藏域验证和程序赋值即时验证的问题浅析
2016/12/01 Javascript
Bootstrap中glyphicons-halflings-regular.woff字体报404错notfound的解决方法
2017/01/19 Javascript
vue + socket.io实现一个简易聊天室示例代码
2017/03/06 Javascript
基于jquery实现多选下拉列表
2017/08/02 jQuery
了解JavaScript中let语句
2019/05/30 Javascript
详解基于Wepy开发小程序插件(推荐)
2019/08/01 Javascript
JS实现秒杀倒计时特效
2020/01/02 Javascript
[01:11:37]完美世界DOTA2联赛PWL S2 SZ vs FTD.C 第一场 11.19
2020/11/19 DOTA
完美解决python遍历删除字典里值为空的元素报错问题
2016/09/11 Python
用tensorflow搭建CNN的方法
2018/03/05 Python
python学习入门细节知识点
2018/03/29 Python
详谈python在windows中的文件路径问题
2018/04/28 Python
python基础 range的用法解析
2019/08/23 Python
记一次pyinstaller打包pygame项目为exe的过程(带图片)
2020/03/02 Python
如何利用Python动态模拟太阳系运转
2020/09/04 Python
爬虫代理的cookie如何生成运行
2020/09/22 Python
CSS3按钮鼠标悬浮实现光圈效果源码
2016/09/11 HTML / CSS
Bootstrap 学习分享
2012/11/12 HTML / CSS
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
粉红色的鲸鱼:Vineyard Vines
2018/02/17 全球购物
Clarks鞋澳大利亚官方网站:Clarks Australia
2019/12/25 全球购物
台湾7-ELEVEN线上购物中心:7-11
2021/01/21 全球购物
设置器与访问器的定义以及各自特点
2016/01/08 面试题
客户接待方案
2014/02/26 职场文书
培训班主持词
2014/03/28 职场文书
保密协议书范本
2014/04/22 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
兽医医药专业求职信
2014/07/27 职场文书
小学工作总结2015
2015/05/04 职场文书
用Python将库打包发布到pypi
2021/04/13 Python