JavaScript DOM查询,原生js实现元素子节点的获取

在网页网页开发中,经常会需要获取某个网页元素的子元素,然后对其进行时间绑定、或样式修改等网页行为。这些操作对于jquery来说很容易,但是对于原生js会稍微麻烦一些。

一、childNodes

子节点的操作,大部分人首先想到的肯定是“childNodes”。childNodes属性可以获取节点元素的子节点,并将获取到的子节点封装成一个对象:

<div class="test" id="test">
  <p>1</p>
  <p>3</p>
  <p>5</p>
</div>

<script>
  var a = document.getElementById("test");
  var b = a.childNodes;
</script>

上面的代码就把childNodes获取到的对象保存在了b中,但这样写也会带来一个问题:

上面的div中有3子子元素,但是console.log(b)却发现输出的对象中有七个元素,那为什么会多出四个元素呢?

因为根据dom的标准,标签之间的回车空格等特殊字符属于文本节点,上面的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"){
                a.removeChild(b[i]);
            }
        }

(网上有人判断这么写:if(b[i].nodeName == "#text" && !/\s/.test(b.nodeValue)),但我觉得&&后面那一半完全没有用。因为文本节点不管内容是什么,它的nodeValue属性的值都是null,它必然不等于/\s/,如果我的理解不对,麻烦评论告知以下)

想要操作子元素,只需要b加下标就可以了,比如想要修改第一个p标签的颜色:

b[0].style.color='red';

 

二、child属性

child属性比childNodes方便得多,它不会返回文本节点。因此只需要一行代码就可以完成上面的操作

        var a = document.getElementById("test").children;

修改第一个p标签的颜色

        a[0].style.color="red";

还有firstchild,lastchild这种见名知意的属性就不展开说了

三、获取后代节点

还是上面的例子,通过getElementById、getElementsByTagName、getElementBysClassName都可以获得后代元素节点。

下面的方法可以实现共和之前两种方法相同的功能:

        var a = document.getElementById("test");
        var b = a.getElementsByTagName('p');

还可以把方法中的p改为“*”,这样所有的子节点都能获取到,不管是什么类型的标签。

但是这种方法会获div的所有后代节点,只要符合条件,就会被获取到,即使它不是子节点:

<--下面的例子里,inner_test模块里的p标签也会被获取到-->
<div class="test" id="test">   <p>1</p>   <p>3</p>   <p>5</p>
  <div class = "inner_test">
    <p>我不是test的子节点</p>
  </div> </div>

除此之外,getElementsByTagName还有一个致命的缺点,就是它不能兼容ie6、7、8。

四、querySelectorAll,强烈推荐!

querySelectorAll/querySelector的参数是选择器,换句话说:任何选择器都可以作为它的参数,可以想象他的灵活度之高,定位之精准。

用它来实现的例子就是这样:

var a = document.getElementById("test");
        var b = document.querySelectorAll('.test>p');

通过子类选择器,就可以获取test模块下的类型为p的子节点,这种方法是目前我知道的最好的方法,不但写起来简单,而且运算量也比较小,而且还兼容ie8

<div id="navDiv"><a href="javascript:;"></a><a href="javascript:;"></a><a href="javascript:;"></a><a href="javascript:;"></a><a href="javascript:;"></a></div>

转载于:https://www.cnblogs.com/iszhangk/p/10869009.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值