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

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

  • 相关阅读:
    Excel中的日期时间计算,套路很全
    WPS表格 制作甘特图
    关于海康威视与Unity3d集成冲突问题解决
    海康威视(iOS集成)
    Objective-C
    Android中windowTranslucentStatus与windowTranslucentNavigation的一些设置(转)
    Could not symlink include/node/android-ifaddrs.h
    dyld`__abort_with_payload:
    about the libiconv.2.dylib
    Intent的作用和表现形式简单介绍
  • 原文地址:https://www.cnblogs.com/dexjinkey/p/6117896.html
Copyright © 2011-2022 走看看