各浏览器中querySelector和querySelectorAll的实现差异分析


Posted in Javascript onMay 23, 2012

querySelector和querySelectorAll是W3C提供的新的查询接口

querySelector和querySelectorAll是W3C提供的 新的查询接口,其主要特点如下:

1、querySelector只返回匹配的第一个元素,如果没有匹配项,返回null。
2、querySelectorAll返回匹配的元素集合,如果没有匹配项,返回空的nodelist(节点数组)。
3、返回的结果是静态的,之后对document结构的改变不会影响到之前取到的结果。

这两个方法都可以接受三种类型的参数:id(#),class(.),标签,很像jquery的选择器。

var obj = document.querySelector("#id");var obj = document.querySelector(".classname");
var obj = document.querySelector("div");
var el = document.body.querySelector("style[type='text/css'], style:not([type])");
var elements = document.querySelectorAll("#score>tbody>tr>td:nth-of-type(2)");
var elements = document.querySelectorAll("#id1, #id2, .class1, class2, div a, #list li img");

目前IE8+,ff,chrome都支持此api(IE8中的selector string只支持css2.1的)
浏览器支持查看

module dom {
[Supplemental, NoInterfaceObject]
interface NodeSelector {
Element querySelector(in DOMString selectors);
NodeList querySelectorAll(in DOMString selectors);
};
Document implements NodeSelector;
DocumentFragment implements NodeSelector;
Element implements NodeSelector;
};

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 1 3.5 (1.9.1)bug 416317 9 8 (CSS2 selectors only) 10 3.2 (525.3)WebKit bug 16587
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 2.1 yes 9 10.0 3.2

从接口定义可以看到Document、DocumentFragment、Element都实现了NodeSelector接口。即这三种类型的元素都拥有者两个方法。querySelector和querySelectorAll的参数须是符合 css selector 的字符串。不同的是querySelector返回的是一个对象,querySelectorAll返回的一个集合(NodeList)。

目前 IE8/9及Firefox/Chrome/Safari/Opera 的最新版已经支持它们。

如想获取页面class属性为"red"的元素,除了使用document.getElementsByClassName('red')还可以使用document.querySelector('.red')和document.querySelectorAll('.red')。

但Element.querySelector和Element.querySelectorAll的实现有错误,如下

<div id="d1"> 
<p><a href="http://www.sina.com.cn">SINA</a></p> 
</div> 
<script type="text/javascript"> 
function $(id){return document.getElementById(id);} 
var d1 = $('d1'); 
var obj1 = d1.querySelector('div a'); 
var obj2 = d1.querySelectorAll('div a'); 
alert(obj1); // -> http://www.sina.com.cn/ 
alert(obj2.length); // -> 1 
</script>

如果支持这两个方法的浏览器可以看到分别弹出了“http://www.sina.com.cn/”,和 “1”。说明查询到了想要的元素或元素集合。这与W3C的定义却是不合的,根据定义应该是在元素d1范围内查找"div a",而d1内压根没有div。因此应该分别返回null,空集合。

jQuery1.4.2 及之前版本中只使用了document.querySelectorAll,没有使用Element.querySelectorAll。 jQuery1.4.3 后使用了Element.querySelectorAll,但做了修复。在选择器前加了"#__sizzle__"以强制其在指定元素内查找(3903-3918行)。简化下

function $(id){return document.getElementById(id);} 
var d1 = $('d1'); 
var obj1 = d1.querySelector('div a'); 
var obj2 = d1.querySelectorAll('div a'); 
var old = d1.id, id = d1.id = "__sizzle__"; 
try { 
var query = '#' + id + ' div a'; 
alert(d1.querySelector( query )); 
alert(d1.querySelectorAll( query ).length); 
} catch(e) { 
} finally { 
old ? d1.id = old : d1.removeAttribute( "id" ); 
}

实现很巧妙,指定范围的元素如果有id,将其保留在old,"__sizzle__"赋值其作为临时id,在选择器"div a"前指定查找范围为"#__sizzle__",即d1。finally语句来最后清理,如果指定范围的元素本身有id将其恢复为old,没有则去掉临时的id属性"__sizzle__"。

相关:
http://msdn.microsoft.com/en-us/library/cc288169%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/cc304115%28VS.85%29.aspx
https://developer.mozilla.org/En/DOM/Document.querySelector
https://developer.mozilla.org/En/DOM/Document.querySelectorAll
https://developer.mozilla.org/En/DOM/element.querySelector
https://developer.mozilla.org/En/DOM/Element.querySelectorAll

Javascript 相关文章推荐
js动态添加onclick事件可传参数与不传参数
Jul 29 Javascript
javascritp添加url参数将参数加入到url中
Sep 25 Javascript
无需 Flash 使用 jQuery 复制文字到剪贴板
Apr 26 Javascript
Javascript点击按钮随机改变数字与其颜色
Sep 01 Javascript
微信小程序 仿猫眼实现实例代码
Mar 14 Javascript
微信小程序tabBar底部导航中文注解api详解
Aug 16 Javascript
jQuery实现可兼容IE6的淡入淡出效果告警提示功能示例
Sep 20 jQuery
parabola.js抛物线与加入购物车效果的示例代码
Oct 25 Javascript
从零开始最小实现react服务器渲染详解
Jan 26 Javascript
vue如何进行动画的封装
Sep 26 Javascript
微信小程序实现留言板(Storage)
Nov 02 Javascript
vue缓存的keepalive页面刷新数据的方法
Apr 23 Javascript
jQuery-onload让第一次页面加载时图片是淡入方式显示
May 23 #Javascript
jquery.pagination.js 无刷新分页实现步骤分享
May 23 #Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
May 23 #Javascript
使用JQuery和CSS模拟超链接的用户单击事件的实现代码
May 23 #Javascript
基于jquery tab切换(防止页面刷新)
May 23 #Javascript
jQuery下通过replace字符串替换实现大小图片切换
May 22 #Javascript
js面向对象 多种创建对象方法小结
May 21 #Javascript
You might like
php读取30天之内的根据算法排序的代码
2008/04/06 PHP
配置eAccelerator和XCache扩展来加速PHP程序的执行
2015/12/22 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
2017/09/26 PHP
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
微信小程序 开发工具快捷键整理
2016/10/31 Javascript
Vue波纹按钮组件制作
2018/04/30 Javascript
vue服务端渲染缓存应用详解
2018/09/12 Javascript
小程序:授权、登录、session_key、unionId的详解
2019/05/15 Javascript
JavaScript判断对象和数组的两种方法
2019/05/31 Javascript
微信小程序之下拉列表实现方法解析(附完整源码)
2019/08/23 Javascript
node.js爬虫框架node-crawler初体验
2020/10/29 Javascript
pymongo实现控制mongodb中数字字段做加法的方法
2015/03/26 Python
用Python代码来解图片迷宫的方法整理
2015/04/02 Python
深入浅析ImageMagick命令执行漏洞
2016/10/11 Python
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
Python实现的矩阵转置与矩阵相乘运算示例
2019/03/26 Python
python批量处理文件或文件夹
2020/07/28 Python
利用pandas合并多个excel的方法示例
2019/10/10 Python
详解pyinstaller selenium python3 chrome打包问题
2019/10/18 Python
Python模拟伯努利试验和二项分布代码实例
2020/05/27 Python
css3的transition效果和transfor效果示例介绍
2013/10/30 HTML / CSS
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
杠杆的科学教学反思
2014/01/10 职场文书
继承权公证书
2014/04/09 职场文书
《天安门广场》教学反思
2014/04/23 职场文书
股票投资建议书
2014/05/19 职场文书
上班迟到检讨书
2014/09/15 职场文书
教师党员个人自我剖析材料
2014/09/29 职场文书
机关作风建设工作总结
2014/10/23 职场文书
员工工作能力评语
2014/12/31 职场文书
铁人观后感
2015/06/16 职场文书
MySQL系列之八 MySQL服务器变量
2021/07/02 MySQL
CSS文本阴影 text-shadow 悬停效果详解
2022/05/25 HTML / CSS
vscode内网访问服务器的方法
2022/06/28 Servers
windows11选中自动复制怎么开启? Win11自动复制所选内容的方法
2022/07/23 数码科技