一、时间紧急,废话少说

本文所在的页面藏匿了下面这些代码:

<img id="outside">
<div id="my-id">
<img id="inside">
<div class="lonely"></div>
<div class="outer">
<div class="inner"></div>
</div>
</div>

就是下面这样的表现(为了便于观察,我加了边框背景色和文字):

孤家寡人
outer-inner之间

最内部

首先说点大家都知道的热热身。

  • querySelectorquerySelectorAll IE8+浏览器支持。
  • querySelector返回的是单个DOM元素;querySelectorAll返回的是NodeList.
  • 我们一般用的多的是document.querySelectorAll, 实际上,也支持dom.querySelectorAll.例如:
    document.querySelector("#my-id").querySelectorAll("img")

    选择的就是里面这个妹子。例如,我在控制台输出该选择NodeList的长度和id,如下截图:

好了,上面都是众所周知的,好,下面开始展示点有意思的。

大家看下下面2行简单的查询语句:

document.querySelectorAll("#my-id div div");
document.querySelector("#my-id").querySelectorAll("div div");

提问:上面两个语句返回的NodeList的内容是否是一样的?

给大家1分钟的时间思考下。

//zxx: 假设1分钟已经过去了

好了,答案是:不一样的。估计不少人跟我一样,会认为是一样的。

实际上:

document.querySelectorAll("#my-id div div").length === 1;
document.querySelector("#my-id").querySelectorAll("div div").length === 3;

大家如果有疑问,可以在控制台测试下,下图就是我自己测试的结果:

为啥会这样?

第一个符合我们的理解,不解释。那下一个语句,为何返回的NodeList长度是3呢?

首先,遍历该NodeList会发现,查询的三个dom元素为:div.lonely, div.outer, div.inner.

奇怪,奇怪,怎么会是3个呢?

jQuery中有个find()方法,大家很可能受到这个方法影响,导致出现了一些认知的问题:

$("#my-id").find("div div").length === 1;

如果使用find方法,则是1个匹配;由于结构和作用类似,我们很自然疑问原生的querySelectorAll也是这个套路。真是太错特错!!

要解释,为何NodeList长度是3,只要一句话就可以了,我特意加粗标红:

CSS选择器是独立于整个页面的!

什么意思呢?比如说你在页面很深的一个DOM里面写上:

<style>
div div { }
</style>

整个网页,包括父级,只要是满足div div父子关系的元素,全部会被选中,对吧,这个大家应该都清楚的。

这里的querySelectorAll里面的选择器也同样是这也全局特性。document.querySelector("#my-id").querySelectorAll("div div")翻译成白话文就是:查询#my-id的子元素,同时满足整个页面下div div选择器条件的DOM元素们。

我们页面往上滚动看看原始的HTML结构,会发现,在全局视野下,div.lonely, div.outer, div.inner全部都满足div div这个选择器条件,于是,最终返回的长度为3.

二、:scope与区域选择限制

其实,要想querySelectorAll后面选择器不受全局影响,也是有办法的,就是使用目前还处于实验阶段:scope伪类,其作用就是让CSS是在某一范围内使用。此伪类在CSS中使用是大头,但是也可以在querySelectorAll语句中使用:

document.querySelector("#my-id").querySelectorAll(":scope div div");

兼容性如下:

我写此文时候是15年11月初,目前基本上就FireFox浏览器支持,我估计,以后,会支持越来越多的。为什么呢?

因为Web Components需要它,可以实现真正独立封装,不会受外界影响的HTML组件。

关于:scope目前支持尚浅,时机未到,我就没必要乱展开了,点到为止。

三、结语还是要的

参考文章:querySelectorAll from an element probably doesn’t do what you think it does

感谢阅读,欢迎纠错,欢迎交流!

DOM元素querySelectorAll可能让你意外的特性表现的更多相关文章

  1. HTML5中DOM元素的querySelector/querySelectorAll的工作机制

    在HTML5中,提供了强大的DOM元素选择API querySelector/querySelectorAll,允许使用JavaScript代码来完成类似CSS选择器的DOM元素选择功能.通常情况下, ...

  2. 【面试必备】javascript操作DOM元素

    前言 时间过的真快,不知不觉就到年底了.问问自己,这一年你对自己的工作满意吗? 评价标准是什么呢?当然是马云的那两条准则了:钱给到了吗?干的爽吗?如果答案都是no,那么,你准备好跳槽了吗? 为了应对年 ...

  3. HTML DOM 元素对象

    HTML DOM 元素对象 HTML DOM 节点 在 HTML DOM (Document Object Model) 中, 每个东西都是 节点 : 文档本身就是一个文档对象 所有 HTML 元素都 ...

  4. JS1 js获取dom元素方法

     js获取dom元素方法  1.通过ID选取元素(getElementById) 1)使用方法:document.getElementById("domId")         其 ...

  5. riot.js教程【三】访问DOM元素、使用jquery、mount输入参数、riotjs标签的生命周期

    前文回顾 riot.js教程[二]组件撰写准则.预处理器.标签样式和装配方法 riot.js教程[一]简介 访问DOM元素 你可以通过this.refs对象访问dom元素 而且还有大量的属性简写方式可 ...

  6. Html开发中document.getElementByTagName无法找到所有DOM元素的问题解决方法

    let eleList = document.querySelectorAll('li') for (let i = 0; i < eleList.length; i++) { // 遍历操作 ...

  7. JS----获取DOM元素的方法(8种)

    什么是HTML DOM 文档对象模型(Document Object Model),是W3C组织推荐的处理可扩展置标语言的标准编程接口.简单理解就是HTML DOM 是关于如何获取.修改.添加或删除 ...

  8. JavaScript DOM 元素属性 状态属性

    JavaScript DOM 元素属性 状态属性 版权声明:未经允许,严禁转载! 元素的属性 核心 DOM 为我们提供了操作元素标准属性的统一 API. 所有属性节点都储存在元素的 attribute ...

  9. JS选取DOM元素的方法

    摘自JavaScript权威指南(jQuery根据样式选择器查找元素的终极方式是 先用getElementsByTagName(*)获取所有DOM元素,然后根据样式选择器对所有DOM元素进行筛选) 今 ...

随机推荐

  1. 【转】el表达式的判断符

    el表达式一般不直接用==判断是否相等 != > < >= <=之类的表示不等于 大于 小于 大于等于 小于等于,而是使用字母表示的表达式,他们的表示如下: == eq 等于 ...

  2. android .apk安装时遇到NSTALL_FAILED_CONTAINER_ERROR错误

    在一台酷派上装apk时遇到问题: android Installation error: INSTALL_FAILED_CONTAINER_ERROR 遇到问题后baidu google修改为andr ...

  3. webpack 往右一点之 “你好,初次见面”

    webpack  模块打包器 模块化工具的目标: 将依赖树拆分成按需加载的块 初始化加载的耗时尽量少 各种静态资源都可以视作模块 将第三方库整合成模块 自定义打包逻辑 适合大项目

  4. AX7: Install a deployable package

    Table of Contents Introduction Key concepts Collect topology configuration data Generate a runbook f ...

  5. 如何获取TypedArray?

    当我们需要自定义控件的时候经常会使用到TypedArray这个类,使用完之后必须调用recycler()函数.... 但是如何获取呢? 有如下几个方式: context(实际最后调用的是context ...

  6. 使用Git命令上传本地项目

    前提,安装git,使用cmd进入项目根目录. 初始化git init 再添加文件git add .git commit -m '项目名' 上传项目到Github仓库git remote add ori ...

  7. cursor 鼠标样式——属性

    取值: [ [<uri> ,]* [ auto | crosshair | default | pointer | move | e-resize | ne-resize | nw-res ...

  8. spring3 项目更新

    列志华 (组长) http://www.cnblogs.com/liezhihua/ 团队guihub https://github.com/LWHTF/OrderingFood 黄柏堂 http:/ ...

  9. redis常用总结

    1. 使用redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,li ...

  10. JAVA EE中session的理解

    转自[互动百科]http://www.baike.com/wiki/Session   Session Session:在计算机中,尤其是在网络应用中,称为“会话”.Session直接翻译成中文比较困 ...