在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. Swift 使用CollectionView 实现图片轮播封装就是这样简单

    前言: 这篇你可以学会自定义视图,创建collectionView,协议的使用,定时器; 自制图片 先上Demo:Github上封装好的下载即用, 好用请Star Thanks首先新建一个继承于UIV ...

  2. 309. Best Time to Buy and Sell Stock with Cooldown

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  3. Ubuntu安装取色软件

    sudo apt-get install Gpick

  4. JavaScript ECAMScript5 新特性——get/set访问器

    之前对get/set的理解一直有误,觉得get set 是对象属性方法.看了别人的博客也有很多疑问,今天系统的做了很多测试终于弄明白了.(自己通过看书和写demo测试的,如有不对欢迎大家批评指正) g ...

  5. 模糊查询的like '%$name$%'的sql注入避免

    Ibatis like 查询防止SQL注入的方法 Ibatis like 查询防止SQL注入的方法 mysql: select * from tbl_school where school_name ...

  6. 测试用例生成工具ALLPAIRS(转)

    ALLPAIRS是一个测试用例设计工具,用于Windows,但移植到了多种平台,以适应该脚本文件的一些小改动.它自动对所有实验技术进行设计,通过这个工具的方法可以在海量的数据组合中选择少量的数据生成测 ...

  7. excel读取 工具类

    package cn.yongche.utils; import java.io.File; import java.io.FileInputStream; import java.io.IOExce ...

  8. 路由器扫描的Java源码

    这个源码不是本人写的,是我原来的领导写的,我们都叫他东哥,这个是东留给我的一个小资源,好佩服他哦,这个东西可以用来扫描全世界的路由器,破解路由器账户和密码 当然是简单的了.我能力不够没有更完善的补充下 ...

  9. 利用SOLR搭建企业搜索平台 之——配置文件

    运行solr是个很简单的事,如何让solr高效运行你的项目,这个就不容易了.要考虑的因素太多.这里很重要一个就是对solr的配置要了解.懂得配置文件每个配置项的含义,这样操作起来就会如鱼得水! 在so ...

  10. Android OTA 升级之三:生成recovery.img

    Android OTA 升级之三:生成recovery.img 作者: 宋立新 Email:zjujoe@yahoo.com 前言 得到了ota升级包后,我们就可以用它来升级系统了.Android 手 ...