再谈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 相关文章推荐
检测jQuery.js是否已加载的判断代码
May 20 Javascript
如何在一个页面显示多个百度地图
Apr 07 Javascript
jquery插件ajaxupload实现文件上传操作
Dec 09 Javascript
jQuery基础知识点总结(必看)
May 31 Javascript
Js操作DOM元素及获取浏览器高宽的简单方法
Sep 08 Javascript
基于jQuery实现Tabs选项卡自定义插件
Nov 21 Javascript
如何理解Vue的作用域插槽的实现原理
Aug 19 Javascript
JavaScript 下载svg图片为png格式
Jun 21 Javascript
对vue中v-if的常见使用方法详解
Sep 28 Javascript
小程序云开发如何实现图片上传及发表文字
May 17 Javascript
vue+Element实现搜索关键字高亮功能
May 28 Javascript
Vue项目开发常见问题和解决方案总结
Sep 11 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 curl_setopt()函数实例代码与参数分析
2011/06/02 PHP
很让人受教的 提高php代码质量36计
2012/09/05 PHP
PHP.ini中配置屏蔽错误信息显示和保存错误日志的例子
2014/05/12 PHP
ThinkPHP的I方法使用详解
2014/06/18 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
Google Map API更新实现用户自定义标注坐标
2009/07/29 Javascript
Javascript 继承机制的实现
2009/08/12 Javascript
jquery 操作css样式、位置、尺寸方法汇总
2014/11/28 Javascript
JavaScript对数字的判断与处理实例分析
2015/02/02 Javascript
JS取模、取商及取整运算方法示例
2016/10/13 Javascript
微信小程序 实现列表项滑动显示删除按钮的功能
2017/04/13 Javascript
angular directive的简单使用总结
2017/05/24 Javascript
React 子组件向父组件传值的方法
2017/07/24 Javascript
vue interceptor 使用教程实例详解
2018/09/13 Javascript
JQuery+drag.js上传图片并且实现图片拖曳
2020/11/18 jQuery
Python引用模块和查找模块路径
2016/03/17 Python
使用wxpy实现自动发送微信消息功能
2020/02/28 Python
Django-imagekit的使用详解
2020/07/06 Python
python文件路径操作方法总结
2020/12/21 Python
python3 googletrans超时报错问题及翻译工具优化方案 附源码
2020/12/23 Python
前端面试必备之CSS3的新特性
2017/09/05 HTML / CSS
英国露营设备和户外服装购物网站:Simply Hike
2019/05/05 全球购物
介绍一下常见的木马种类
2014/11/15 面试题
业务部主管岗位职责
2014/01/29 职场文书
大学生感恩父母演讲稿
2014/08/28 职场文书
个人房屋转让协议书范本
2014/10/26 职场文书
2014年食品安全工作总结
2014/12/04 职场文书
拾金不昧表扬信怎么写
2015/05/04 职场文书
2015年基层党支部工作总结
2015/05/21 职场文书
2015年环境整治工作总结
2015/05/22 职场文书
新郎结婚感言
2015/07/31 职场文书
小学秋季运动会加油口号及加油稿
2019/08/19 职场文书
position:sticky 粘性定位的几种巧妙应用详解
2021/04/24 HTML / CSS
python使用glob检索文件的操作
2021/05/20 Python
git stash(储藏)的用法总结
2022/06/25 Servers