在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的工作机制的更多相关文章

  1. javascript DOM操作之 querySelector,querySelectorAll

    javascript DOM操作之 querySelector,querySelectorAll

  2. html5中output元素详解

    html5中output元素详解 一.总结 一句话总结: output元素是HTML5新增的元素,用来设置不同数据的输出,没什么大用,了解即可 <form action="L3_01. ...

  3. html5中section元素详解

    html5中section元素详解 一.总结 一句话总结: section元素 用来定义文章中的章节(通常应该有标题和段落内容) section元素的作用就是给内容分段,给页面分区 1.section ...

  4. html5中time元素详解

    html5中time元素详解 一.总结 一句话总结: time的使用的话主要是将时间放在datetime属性里面:<time datetime="2015-10-22"> ...

  5. HTML5中dialog元素尝鲜

    对话框(别称模态框,浮层)是web项目中用于用户交互的重要部分,我们最常见的就是js中 alert(),confirm(),但是这个对话框的不美观,也不能自定义样式,所以在开发的过程中,一般根据自己自 ...

  6. jquery中dom元素的attr和prop方法的理解

    一.背景 在编写使用高版本[ jQuery 1.6 开始新增了一个方法 prop()]的jquery插件进行编写js代码的时候,经常不知道dom元素的attr和prop方法到底有什么区别?各自有什么应 ...

  7. 【HTML5】HTML5中video元素事件详解(实时监测当前播放时间)

    html 代码..video后边几个元素,可处理ios 系统的兼容性 <video id="myVideo" controls="controls" po ...

  8. 详解JS中DOM 元素的 attribute 和 property 属性

    一.'表亲戚':attribute和property 为什么称attribute和property为'表亲戚'呢?因为他们既有共同处,也有不同点. attribute 是 dom 元素在文档中作为 h ...

  9. 笔记:HTML5中input元素新增的type值

    在HTML5中,input元素的type值增加了不少,使input的功能强大了很多. 但在各大浏览器中并不是所有的type值都支持. 以下是比较有用.并且浏览器支持的稍好一些的值: type=colo ...

随机推荐

  1. iOS开发多线程--技术方案

    pthread 实现多线程操作 代码实现: void * run(void *param) {    for (NSInteger i = 0; i < 1000; i++) {         ...

  2. React的CSS

    1.代码 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="U ...

  3. yafeilinux.com的开源项目非常好的东西

    转自:http://www.yafeilinux.com/?page_id=9 声明:我们网站的资源可以自由下载,转载,但是不能用作商业用途.如有问题请联系我们www.yafeilinux.com . ...

  4. TPaintBox的前世今生

    TPaintBox是一个图形控件,继承于TGraphicControl,并且只有聊聊几个函数和属性,主要就是Canvas和Paint函数,都在这里了: TPaintBox = class(TGraph ...

  5. Sublime Text 2安装汉化破解、插件包安装教程

    原文地址: Sublime Text 2安装汉化破解.插件包安装教程_百度经验 http://jingyan.baidu.com/article/ff4116259b057c12e48237b8.ht ...

  6. http://my.oschina.net/pangyangyang/blog/144495

    http://my.oschina.net/pangyangyang/blog/144495

  7. CentOS下的账户管理

    在Linux中,每个文件都分3类权限:账户本身的权限,账户所在群组的权限和其它权限.账户和群组是多对多的关系,即一个账户可以属于多个群组,一个群组可以包含多个账户.但是,对于每一个已登录的账户,只能存 ...

  8. sql2000无法打开1433端口及解决方法

    1.如果你是win2003,那么一定要安装sql的补丁sp3a以上版本SP 检查你的SQL有没有打补丁,没有的话要打上补丁,检查的方法是在查询分析器中运行:select @@version如果出来的版 ...

  9. Weblogic控制器的部署

    WebLogic的安装 一 WebLogic安装 1.  打开WebLogic安装程序:oepe11_wls1031.exe(我们选用的是WebLogic 10.3g).如图1-1所示: 图1-1   ...

  10. Java异常 —— java.lang.NoClassDefFoundError

    一直使用 Eclipse 来开发 Java . 现学习 Maven,在 cmd 下使用 Java ,出现了这样的异常:Exception in thread "main" java ...