各浏览器中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 相关文章推荐
javascript权威指南 学习笔记之null和undefined
Sep 25 Javascript
15个款优秀的 jQuery 图片特效插件推荐
Nov 21 Javascript
javascript数字格式化通用类 accounting.js使用
Aug 24 Javascript
jquery ajax 局部无刷新更新数据的实现案例
Feb 08 Javascript
node.js中的querystring.parse方法使用说明
Dec 10 Javascript
Js为表单动态添加节点内容的方法
Feb 10 Javascript
javascript事件冒泡实例分析
May 13 Javascript
JS更改select内option属性的方法
Oct 14 Javascript
jQuery使用DataTable实现删除数据后重新加载功能
Feb 27 Javascript
jQuery简易时光轴实现方法示例
Mar 13 Javascript
jQuery实现查看图片功能
Dec 01 jQuery
vue项目如何打包之项目打包优化(让打包的js文件变小)
Apr 30 Vue.js
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的计数器程序
2006/10/09 PHP
php 在文件指定行插入数据的代码
2010/05/08 PHP
Php中使用Select 查询语句的实例
2014/02/19 PHP
PHP实现取得HTTP请求的原文
2014/08/18 PHP
php中通过eval实现字符串格式的计算公式
2017/03/18 PHP
让你的博文自动带上缩址的实现代码,方便发到微博客上
2010/12/28 Javascript
基于jquery自己写tab滑动门(通用版)
2012/10/30 Javascript
鼠标悬浮停留三秒后自动显示大图js代码
2014/09/09 Javascript
javascript属性访问表达式用法分析
2015/04/25 Javascript
js+css实现文字散开重组动画特效代码分享
2015/08/21 Javascript
javascript实现的上下无缝滚动效果
2016/09/19 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
js中Number数字数值运算后值不对的解决方法
2017/02/28 Javascript
JavaScript实现反转字符串的方法详解
2017/04/27 Javascript
Angular如何引入第三方库的方法详解
2017/07/13 Javascript
JS继承与闭包及JS实现继承的三种方式
2017/10/15 Javascript
JavaScript实现省市联动过程中bug的解决方法
2017/12/04 Javascript
JS中用EL表达式获取上下文参数值的方法
2018/03/28 Javascript
JS如何判断对象是否包含某个属性
2020/08/29 Javascript
[03:14]辉夜杯主赛事 12月25日每日之星
2015/12/26 DOTA
Python Mysql数据库操作 Perl操作Mysql数据库
2009/01/12 Python
Python实现的Kmeans++算法实例
2014/04/26 Python
Python实现单词拼写检查
2015/04/25 Python
python中OrderedDict的使用方法详解
2017/05/05 Python
python中学习K-Means和图片压缩
2017/11/20 Python
对Python的zip函数妙用,旋转矩阵详解
2018/12/13 Python
python调用staf自动化框架的方法
2018/12/26 Python
不到20行代码用Python做一个智能聊天机器人
2019/04/19 Python
pow在python中的含义及用法
2019/07/11 Python
公司中秋节活动方案
2014/02/12 职场文书
群众路线个人对照检查材料2014
2014/09/26 职场文书
成绩报告单家长评语
2014/12/30 职场文书
营业员岗位职责范本
2015/04/14 职场文书
感恩教师主题班会
2015/08/12 职场文书
创业计划书之外语培训班
2019/11/02 职场文书
python tqdm用法及实例详解
2021/06/16 Python