在网页网页开发中,经常会需要获取某个网页元素的子元素,然后对其进行事件绑定、或样式修改等行为。这些操作对于jquery来说很容易,但是对于原生js会稍微麻烦一些,这里将介绍四种方法获取元素的子元素(本文推荐第四种方法,如果时间有限,请直接把把滚轮滑到底↓↓↓↓↓)

一、childNodes

childNodes属性可以获取节点元素的子节点,并将获取到的子节点封装成一个对象:

<div class="test" id="test">
  <p></p>
  <p>3</p>
  <p></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=;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[].style.color='red';

二、child属性

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

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

修改第一个p标签的颜色

        a[].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></p>
  <p></p>
  <p></p>
  <div class = "inner_test">
    <p>我不是test的子节点</p>
  </div>
</div>

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

四、querySelector,强烈推荐!

querySelector的参数是选择器,任何选择器都可以作为它的参数:

<div class="first">
<span>张三</span>
</div>
<div id="second">
<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>

可以使用伪类选择器这一特点,使得querySelect非常简单而且灵活,它不仅限于子节点,使用~就可以获取兄弟节点,使用空格就可以获取后代节点

在批量操作节点这方面,querySelectAll也甩出了getElementsByTagName、getElementBysClassName一百条街,

这种方法是目前我知道的最好的方法,简单易懂,而且还能兼容ie8及以上的版本

JavaScript DOM查询,原生js实现元素子节点的获取的更多相关文章

  1. 框架操作DOM和原生js操作DOM比较

    问题引出 对于Angular和React操作DOM的速度,和原生js操作DOM的速度进行了一个比较: 一个同学做的demo 代码如下: <!DOCTYPE html> <html n ...

  2. 创建标签等操作DOM的原生js API

    ()创建新节点 createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体的元素 createTextNode() //创建一个文本节点 ...

  3. 原生js删除元素

    //删除id var idObject = document.getElementById('sidebar'); if (idObject != null) idObject.parentNode. ...

  4. ELementUI 树形控件tree 获取子节点同时获取半选择状态的父节点ID

    使用element-ui  tree树形控件的时候,在选择一个子节点后,使用getCheckedKeys 后,发现只能返回子节点的ID,但是其父节点ID没有返回. 解决办法有三种: 1.element ...

  5. js 字符串分割成字符串数组 遍历数组插入指定DOM里 原生JS效果

    使用的TP3.2 JS字符串分割成字符串数组 var images='{$content.pictureurl} ' ;结构是这样 attachment/picture/uploadify/20141 ...

  6. Javascript学习记录——原生JS实现旋转木马特效

    昨天学习到了JS特效部分,然后老师讲了旋转木马特效的实现,如上图.不过只是讲了通过点击箭头实现图片的切换,对于点击图片本身以及二者联动却是没有讲解. 本着一颗追求完美的心,今天花费了一个中午终于将整个 ...

  7. 原生JS查找元素

    今天写了一个很简单.很粗暴的通过JS根据类来查找DOM元素. 为了降低它的粗暴等级(耗费性能)我给了三个等级. 首先性能最好的,适合FF,CH,IE8,通过querySelectorAll这个API. ...

  8. 原生JS给元素添加class属性

     有下面这三种简单语句. document.getElementsByTagName('body')[0].className = 'snow-container'; //设置为新的 document ...

  9. 原生JS 实现元素排序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. 2019-9-2-dotnet-命名管道名字长度限制

    title author date CreateTime categories dotnet 命名管道名字长度限制 lindexi 2019-09-02 11:54:50 +0800 2019-09- ...

  2. oracle dbms_repcat_admin能带来什么安全隐患

    如果一个用户能执行dbms_repcat_admin包,将获得极大的系统权限. 以下情况可能获得该包的执行权限: 1.在sys下grant execute on dbms_repcat_admin t ...

  3. centos6.5后台进程的切换

    1.运行.sh文件 直接用./sh 文件就可以运行,但是如果想后台运行,即使关闭当前的终端也可以运行的话,需要nohup命令和&命令. (1)&命令 功能:加在一个命令的最后,可以把这 ...

  4. Hdu 4291

    题目链接 这道题, 给我的最大的知识点就是对于去模运算,一定可以找到循环节,这题只不过是嵌套了两层,可以分别找到循环节.关于这题如何找循环节的,直接暴力,网上也有很多. 找到循环节之后,另一个知识点就 ...

  5. 设备 VMnet0 上的网络桥接当前未在运行。

    早上,我打开我的虚拟机,却发现一个问题, 桥接网络怎么都连接不上. 报的是如下的错误 ------------------------------ 设备 VMnet0 上的网络桥接当前未在运行.该虚拟 ...

  6. pytorch 多GPU训练总结(DataParallel的使用)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/weixin_40087578/artic ...

  7. iOS 内存管理arc

    http://www.tekuba.net/program/346/ ios自动释放池(autoreleasepool #import <Foundation/Foundation.h> ...

  8. bzoj4152 The Captain

    Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2 ...

  9. ES6对象的super关键字

    super是es6新出的关键字,它既可以当作函数使用,也可以当作对象使用,两种使用方法不尽相同 1.super用作函数使用的时候,代表父类的构造函数,es6规定在子类中使用this之前必须先执行一次s ...

  10. 2019-8-31-cmd-如何跨驱动器移动文件夹

    title author date CreateTime categories cmd 如何跨驱动器移动文件夹 lindexi 2019-08-31 16:55:58 +0800 2019-02-27 ...