zoukankan      html  css  js  c++  java
  • JavaScript DOM查询,原生js实现元素子节点的获取

      每个网页都是一个dom树,网页中所有的内容都是这个树上的一个节点。JavaScript的工作就是操作这些节点,对节点进行查增删改操作,或是给节点绑定事件。

                                                                   网页

                                                        dom树

    要操作dom节点,首先要获取到dom节点。这里我介绍几个原生js获取元素子节点的方法:

    一、通过标签的属性值获取后代节点 

    以getElementBy开头的方法,可以根据具体的属性获取元素的后代节点。这些方法不只会获取子节点,他也会获取到所有符合条件的后代节点。

    方法 依据属性 兼容性 其他
    getElementById id

    兼容性好,推荐使用

    如果存在多个id相同的元素,只会返回第一个

    getElementsByTagName 标签名 不兼容ie8及以下版本  返回所有符合条件的元素的集合
    getElementsByName name 不兼容ie8及以下版本  返回所有符合条件的元素的集合
    getElementsByClassName class 不兼容ie8及以下版本 返回所有符合条件的元素的集合

     以getElementById为例,尽管有两个id为’Jan‘的元素,但是只会获取到第一个:

    <html>
        <head>
        </head>
        <body>
            <p id='Jan' class='test'>1</p>
            <p id='Jan' class='test'>2</p>
            <p id='Mar'>3</p>
        </body>
        <script type="text/javascript">
            var j=document.getElementById('Jan');
            console.log(j);
        </script>
    </html>

    需要注意的是,在同一个文件中出现重复id是不符合规范的,应当尽量避免这样使用。

    如果将上面代码中的getElementById('Jan')换成 getElementsByTagName('p')或者是getElementsByClassName('test')将会获取到符合条件的结果集。

    二、child属性

    每个dom元素都是一个对象,在dom元素对象中有四个专门用于获取子元素的属性:

    属性名 作用 其他
    childNodes 获取所有子节点 不推荐使用,如果有空格,会作为文本节点获取到
    child 获取所有子节点 推荐使用
    firstChild 获取首个子节点 推荐使用
    lastChild 获取最后一个子节点 推荐使用

    这四个属性都不存在兼容性问题,除了childNodes之外都是比较好用的。

    1. childNodes

    childNodes属性可以获取元素的所有子节点,并封装到一个数组中,可以通过下标来获取某个子元素:

    <html>
        <head>
        </head>
        <body>
            <div class="test" id="test">
              <p>1</p>
              <p>3</p>
              <p>5</p>
            </div>
        </body>
        <script>
            var a = document.getElementById("test");
            console.log(a.childNodes);
        </script>
    </html>

    但是childNodes属性有一个问题,class=‘test’的div中只有3子节点,执行结果却有7个节点:

    因为根据在网页中,标签之间的回车空格等特殊字符属于一个p元素,上面的div中输入了4个回车,因此会多出四个text节点:

     

    要解决这个问题有两个方法:

    方法一:去掉所有的回车空格等特殊字符,但是会影响程序的可读性和代码的规范。

    方法二:动态过滤掉空白字符:

    通过for循环遍历对象中的所有元素,删除纯文本元素。

    完整的代码就是这样:

            var a = document.getElementById("test");
            var b = a.childNodes;
            for(i=0;i<b.length;i++){
                if(b[i].nodeName == "#text"&& !/s/.test(b.nodeValue)){
                    a.removeChild(b[i]);
                }
            }

    第二种方法每次查询之前,都要先执行一段过滤代码。这样会影响程序的执行效率,因此childNodes属性不建议使用。

    2. children

    相比childNodes,children属性不会将空格作为文本节点获取。因此就不需要额外的去除空格操作,获取节点的方式和chlidNodes属性相同。

    还是用上面的代码,将 a.childNodes 修改为 a.child 之后,会获取到三个p元素,这就是通常希望得到的结果。

    chilren和childNodes属性存在的缺点是会获取全部的子节点,某些情况下使用时需要筛选,不够灵活。

    3. firstChild&lastChild

    firstChild会获取首个子节点,相当于children[0]的效果。

    lastChild会获取最后一个子节点,相当于children[children.length-1]

    三、querySelector方法,强烈推荐!

    querySelector的参数是css选择器,任何选择器都可以作为它的参数,这样就使得它非常方便灵活:

    比如获取class=‘test’的标签下的第一个子元素,可以这样写querySelector('.test  > * '),也可以指定子元素的类型querySelector('.test  > span '),或者是:classquerySelector('.test  > #f_div')

    还可以使用querySelectorAll方法,这样会获取所有满足条件的元素,而不只是获取第一个元素。

    <div class="first">
        <span>张三</span>
    </div>
    <div id="second">
        <div id=f_div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
    <script>
        //通过类选择器获取节点
        doucument.querySelector('.first');
        //通过id选择器获取节点
        doucument.querySelector('#second');
        //通过伪类选择器获取子节点
        document.querySelector('.first>span');
        //确认selectAll批量获取节点
        document.querySelectorAll('#second>div');
    </script>

    总体来说,我比较推荐使用querySelector方法,因为它更加灵活,使用作为css选择器进行选择非常方便。当然querySelector方法不只可以获取元素的子节点,它可以获取任何节点。querySelector方法可以兼容到IE8,基本能满足前端开发兼容性的需要。

  • 相关阅读:
    #ifndef 、 #define 、#endif使用解释
    基于小熊派Hi3861鸿蒙开发的IoT物联网学习【六】--智慧农业MQTT数据上传华为云
    C语言学习(三)
    c语言学习篇二【基础语法】
    简单图解OSI七层网络模型
    基于小熊派Hi3861鸿蒙开发的IoT物联网学习【五】
    使用Doxygen生成html/chm范例,方便源码阅读
    李宏毅《深度学习》P1----机器学习介绍
    keras实现Alexnet (cifar10数据集)
    cmake条件编译
  • 原文地址:https://www.cnblogs.com/iszhangk/p/10869009.html
Copyright © 2011-2022 走看看