再谈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 相关文章推荐
IE JS无提示关闭窗口不提示的方法
Apr 29 Javascript
Dojo 学习要点
Sep 03 Javascript
jquery判断字符输入个数(数字英文长度记为1,中文记为2,超过长度自动截取)
Oct 15 Javascript
解决JS浮点数运算出现Bug的方法
Mar 12 Javascript
jquery中插件实现自动添加用户的具体代码
Nov 15 Javascript
分享网页检测摇一摇实例代码
Jan 14 Javascript
JS实现的简单轮播图运动效果示例
Dec 22 Javascript
微信小程序组件之srcoll-view的详解
Oct 19 Javascript
Bootstrap导航菜单点击后无法自动添加active的处理方法
Aug 10 Javascript
详解Vue iview IE浏览器不兼容报错(Iview Bable polyfill)
Jan 07 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
Jun 16 Javascript
vue开发简单上传图片功能
Jun 30 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
是否存在第一台收音机的说法
2021/03/01 无线电
PHP将整个网站生成HTML纯静态网页的方法总结
2012/02/05 PHP
初步介绍PHP扩展开发经验分享
2012/09/06 PHP
详解PHP对象的串行化与反串行化
2016/01/24 PHP
PHP+Ajax实现的检测用户名功能简单示例
2019/02/12 PHP
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
2012/01/15 Javascript
js+css实现的简单易用兼容好的分页
2013/12/30 Javascript
jQuery插件pagination实现分页特效
2015/04/12 Javascript
js代码实现随机颜色的小方块
2015/07/30 Javascript
全面解析Bootstrap排版使用方法(标题)
2015/11/30 Javascript
js防阻塞加载的实现方法
2016/09/09 Javascript
详解微信小程序开发之城市选择器 城市切换
2017/01/17 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
vue实现登陆登出的实现示例
2017/09/15 Javascript
Vue2 配置 Axios api 接口调用文件的方法
2017/11/13 Javascript
详解vue 项目白屏解决方案
2018/10/31 Javascript
nodejs 使用 js 模块的方法实例详解
2018/12/04 NodeJs
微信小程序云开发 搭建一个管理小程序
2019/05/17 Javascript
vue实现带复选框的树形菜单
2019/05/27 Javascript
koa-passport实现本地验证的方法示例
2020/02/20 Javascript
记录一次websocket封装的过程
2020/11/23 Javascript
Python探索之自定义实现线程池
2017/10/27 Python
通过shell+python实现企业微信预警
2019/03/07 Python
HTML5实现简单图片上传所遇到的问题及解决办法
2016/01/20 HTML / CSS
Staples加拿大官方网站:办公用品一站式采购
2016/09/25 全球购物
HUGO BOSS美国官方网上商店:世界知名奢侈品牌
2017/08/04 全球购物
英国最大的经认证的有机超市:Planet Organic
2018/02/02 全球购物
法律七进实施方案
2014/03/15 职场文书
买房委托公证书
2014/04/08 职场文书
食品安全标语
2014/06/07 职场文书
2014年会计人员工作总结
2014/12/10 职场文书
餐饮服务员岗位职责
2015/02/09 职场文书
出国留学英文自荐信
2015/03/25 职场文书
2015年采购工作总结
2015/04/10 职场文书
审查起诉阶段律师意见书
2015/05/19 职场文书
SQL中的连接查询详解
2022/06/21 SQL Server