HTML5中DOM元素的querySelector/querySelectorAll的工作机制
在HTML5中,提供了强大的DOM元素选择API querySelector/querySelectorAll,允许使用JavaScript代码来完成类似CSS选择器的DOM元素选择功能。通常情况下,我们都是使用的document.querySelector/querySelectorAll来选择DOM元素,但是有些时候会使用DOM元素上的querySelector/querySelectorAll方法,此时就有些怪异了。
比如说,下面的这样一个HTML页面(示例页面中为了方面说明问题,我为每个元素都加上了ID,但是我们不使用ID选择器来选择元素):
<body>
<span id="s0">This is a span direct child of body</span>
<div id="d1" style="border: 1px solid red;">
This is div d1
<div id="d1-1" style="border: 1px solid blue;">
This is div d1-1 <br/>
<span id="d1-1-1">This span d1-1-1</span>
</div>
<span id="d1-2">This is span d1-2</span>
</div>
</body>
在这个场景中,元素div#d1有2个子元素,分别是div#d1-1和span#d1-2,而元素div#d1-1有一个span#div-1-1-1的子元素。如果我想从div#d1上选择span#d1-1-1,如果使用子元素选择器的话,在jQuery中看起来应该是这样的:
$("#d1").find("div > span")
这段代码会返回span#d1-1-1,就是我们预期的结果。
那么对应到HTML5中的选择器API就应该是这样写的:
var d1 = document.querySelector("#d1");
var spans = d1.querySelectorAll("div > span")
你期望上面这段代码会返回span#d1-1-1,但是实际上的运行结果会连同span#d1-1一并返回!如下图所示:

这个……实在是让我迷惑了一阵子。查阅了一下文档,虽然没有找到官方的说明,但是也基本明白了DOM元素的querySelector和querySelectorAll的运行逻辑了。
当在一个DOM元素上调用querySelector/querySelectorAll的时候,查找机制是这样的:首先在document的范围内进行查找所有满足选择器条件的元素,在上面这段代码中,我们的选择器是div > span,就是所有的直接父元素为div的span元素。然后,再看哪些元素是调用querySelector/querySelectorAll的元素的子元素,这些元素将会被返回。这也就说明了为什么d1.querySelectorAll("div > span") 会连同span#d1-2一并返回。
所以,在DOM元素上调用querySelector/querySelectorAll的时候要小心,最好加上ID选择器进行一个限定,例如上面的代码可以写成:
d1.querySelectorAll("#d1 > div > span");
就会准确的返回我们预期的span#d1-1-1了(当然是这样了,否则就更加的错了!)。
在W3C官方文档中,有提到使用:context (现已更名为:scope)伪类来限制选择器开始工作的上下文,也就是说,可以这样写:
d1.querySelectorAll(":scope > div > span");
但是实际测试的结果是 Safari 6.0.4 和 Chrome 27 统统没有按照预期工作,因为W3C也说了,这个不是标准的。
总结一下,在DOM元素上使用querySelector/querySelectorAll的行为说实话有点儿奇怪,他并不是按照你的预期或者jQuery那种大家都已经习惯了的思路来处理的,所以,有时候可能碰巧你能够获取到正确的结果集,有时候就不是你期望的结果集,这个和你的页面DOM元素的结构和你所使用的选择器都有关系。知道了这个工作原理之后,就不会再发生莫名其妙的问题了。
HTML5中DOM元素的querySelector/querySelectorAll的工作机制的更多相关文章
- javascript DOM操作之 querySelector,querySelectorAll
javascript DOM操作之 querySelector,querySelectorAll
- html5中output元素详解
html5中output元素详解 一.总结 一句话总结: output元素是HTML5新增的元素,用来设置不同数据的输出,没什么大用,了解即可 <form action="L3_01. ...
- html5中section元素详解
html5中section元素详解 一.总结 一句话总结: section元素 用来定义文章中的章节(通常应该有标题和段落内容) section元素的作用就是给内容分段,给页面分区 1.section ...
- html5中time元素详解
html5中time元素详解 一.总结 一句话总结: time的使用的话主要是将时间放在datetime属性里面:<time datetime="2015-10-22"> ...
- HTML5中dialog元素尝鲜
对话框(别称模态框,浮层)是web项目中用于用户交互的重要部分,我们最常见的就是js中 alert(),confirm(),但是这个对话框的不美观,也不能自定义样式,所以在开发的过程中,一般根据自己自 ...
- jquery中dom元素的attr和prop方法的理解
一.背景 在编写使用高版本[ jQuery 1.6 开始新增了一个方法 prop()]的jquery插件进行编写js代码的时候,经常不知道dom元素的attr和prop方法到底有什么区别?各自有什么应 ...
- 【HTML5】HTML5中video元素事件详解(实时监测当前播放时间)
html 代码..video后边几个元素,可处理ios 系统的兼容性 <video id="myVideo" controls="controls" po ...
- 详解JS中DOM 元素的 attribute 和 property 属性
一.'表亲戚':attribute和property 为什么称attribute和property为'表亲戚'呢?因为他们既有共同处,也有不同点. attribute 是 dom 元素在文档中作为 h ...
- 笔记:HTML5中input元素新增的type值
在HTML5中,input元素的type值增加了不少,使input的功能强大了很多. 但在各大浏览器中并不是所有的type值都支持. 以下是比较有用.并且浏览器支持的稍好一些的值: type=colo ...
随机推荐
- iOS开发多线程--技术方案
pthread 实现多线程操作 代码实现: void * run(void *param) { for (NSInteger i = 0; i < 1000; i++) { ...
- React的CSS
1.代码 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="U ...
- yafeilinux.com的开源项目非常好的东西
转自:http://www.yafeilinux.com/?page_id=9 声明:我们网站的资源可以自由下载,转载,但是不能用作商业用途.如有问题请联系我们www.yafeilinux.com . ...
- TPaintBox的前世今生
TPaintBox是一个图形控件,继承于TGraphicControl,并且只有聊聊几个函数和属性,主要就是Canvas和Paint函数,都在这里了: TPaintBox = class(TGraph ...
- Sublime Text 2安装汉化破解、插件包安装教程
原文地址: Sublime Text 2安装汉化破解.插件包安装教程_百度经验 http://jingyan.baidu.com/article/ff4116259b057c12e48237b8.ht ...
- http://my.oschina.net/pangyangyang/blog/144495
http://my.oschina.net/pangyangyang/blog/144495
- CentOS下的账户管理
在Linux中,每个文件都分3类权限:账户本身的权限,账户所在群组的权限和其它权限.账户和群组是多对多的关系,即一个账户可以属于多个群组,一个群组可以包含多个账户.但是,对于每一个已登录的账户,只能存 ...
- sql2000无法打开1433端口及解决方法
1.如果你是win2003,那么一定要安装sql的补丁sp3a以上版本SP 检查你的SQL有没有打补丁,没有的话要打上补丁,检查的方法是在查询分析器中运行:select @@version如果出来的版 ...
- Weblogic控制器的部署
WebLogic的安装 一 WebLogic安装 1. 打开WebLogic安装程序:oepe11_wls1031.exe(我们选用的是WebLogic 10.3g).如图1-1所示: 图1-1 ...
- Java异常 —— java.lang.NoClassDefFoundError
一直使用 Eclipse 来开发 Java . 现学习 Maven,在 cmd 下使用 Java ,出现了这样的异常:Exception in thread "main" java ...