zoukankan      html  css  js  c++  java
  • DOM元素querySelectorAll可能让你意外的特性表现

    一、时间紧急,废话少说

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

    <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

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

  • 相关阅读:
    windows中dos命令指南
    HDU 2084 数塔 (dp)
    HDU 1176 免费馅饼 (dp)
    HDU 1004 Let the Balloon Rise (map)
    变态杀人狂 (数学)
    HDU 2717 Catch That Cow (深搜)
    HDU 1234 开门人和关门人 (模拟)
    HDU 1070 Milk (模拟)
    HDU 1175 连连看 (深搜+剪枝)
    HDU 1159 Common Subsequence (dp)
  • 原文地址:https://www.cnblogs.com/dexjinkey/p/6117896.html
Copyright © 2011-2022 走看看