学科分类
目录
JavaScript网页编程

节点层级

DOM中将HTML文档视为树结构,一个HTML文件可以看作是所有元素组成的一个节点树,各元素节点之间有级别的划分。具体示例如下。

<!DOCTYPE html>

<html>

 <head>

<meta charset="UTF-8">

  <title>测试</title>

 </head>

 <body>

    <a href="#">链接</a>

    <p>段落...</p>

 </body>

</html>

在上述代码中,DOM根据HTML中各节点的不同作用,可将其分别划分为标签节点、文本节点和属性节点。其中,标签节点也被称为元素节点,HTML文档中的注释则单独叫做注释节点。

节点之间的层级关系,最常见的是父子兄层级关系,下面我们以<head>、<body>与<html>节点为例进行介绍,具体如下。

  • 根节点:<html>标签是整个文档的根节点,有且仅有一个。

  • 父节点:指的是某一个节点的上级节点,例如,<html>元素则是<head>和<body>的父节点。

  • 子节点:指的是某一个节点的下级节点,例如,<head>和<body>节点是<html>节点的子节点。

  • 兄弟节点:两个节点同属于一个父节点,例如,<head>和<body>互为兄弟节点。

在讲解了各种节点的层次关系后,接下来我们针对各层级节点的获取进行详细讲解。

1. 获取父级节点

在JavaScript中,可以使用parentNode属性来获得离当前元素的最近的一个父节点,如果找不到父节点就返回为 null,语法格式为:obj.parentNode。其中,obj是一个DOM对象,是通过获取元素的方法来获取的元素,如getElementById()方法等。

接下来我们通过案例形式演示如何获取当前元素的父节点,示例代码如下。

 1  <body>

 2   <div class="demo">

 3    <div class="box">

 4     <span class="child">span元素</span>

 5    </div>

 6   </div>

 7   <script>

 8    var child = document.querySelector('.child');

 9    console.log(child.parentNode);

 10  </script>

 11 </body>

上述代码中,第8行通过querySelector()获取类名为child的span元素,存储到child对象中。第9行会在控制台输出离child元素最近的父级节点(box) 。浏览器预览效果如图1所示。

img

图1 父级节点

2. 获取子级节点

在JavaScript中,可以使用childNodes属性或者children属性两种方式来获得当前元素的所有子节点的集合,接下来我们就分别介绍这两种方式的用法。

(1) childNodes属性

childNodes属性获得的是当前元素的所有子节点的集合,该集合为即时更新的集合。下面我们通过案例的形式演示如何获取当前元素子节点,示例代码如下。

 1  <body>

 2   <ul>

 3    <li>我是li</li>

 4    <li>我是li</li>

 5    <li>我是li</li>

 6    <li>我是li</li>

 7   </ul>

 8   <script>

 9    // DOM 提供的方法(API)获取

 10   var ul = document.querySelector('ul');

 11   var lis = ul.querySelectorAll('li');

 12    console.log(lis);

 13   console.log(ul.childNodes);

 14   console.log(ul.childNodes[0].nodeType);

 15   console.log(ul.childNodes[1].nodeType);

 16  </script>

 17 </body>

上述代码中,第2~7行定义了一个无序列表ul。第10~12行代码用于测试DOM提供的API方法是否能够获取全部li元素。第13行代码使用节点的方式获取ul下的所有的子节点(包括文本节点和元素节点)。第14、15行代码根据nodeType属性来获取文本节点和元素节点的节点类型。输出结果如图2所示。

img

图2 子级节点

在图2中,childNodes属性返回的是NodeList对象的集合,返回值里面包含了元素节点、文本节点等其他类型的节点。如果想要获取childNodes里面的元素节点,需要做专门的处理。在第15行代码下面编写如下代码获取元素节点。

 1  for (var i = 0; i < ul.childNodes.length; i++) {

 2   if (ul.childNodes[i].nodeType === 1) {

 3    console.log(ul.childNodes[i]);

 4   }

 5  }

上述代码中,ul.childNodes[i]是元素节点。需要注意的是,childNodes属性在IE 6~IE 8中不会获取文本节点,在IE 9及以上版本和主流浏览器中则可以获取文本节点。所以在实际开发中一般不提倡使用childNodes。

(2) children

children是一个可读的属性,返回所有子元素节点。children只返回子元素节点,其余节点不返回。目前各大浏览器都支持该属性,在实际开发中推荐使用children。下面我们以案例的形式演示如何获取当前元素子节点,示例代码如下。

 1  <body>

 2   <ol>

 3    <li>我是li</li>

 4    <li>我是li</li>

 5    <li>我是li</li>

 6    <li>我是li</li>

 7   </ol>

 8   <script>

 9    var ul = document.querySelector('ol');

 10   var lis = ul.querySelectorAll('li');

 11   console.log(ul.children);

 12  </script>

 13 </body>

上述代码中,第11行通过ul.children属性获取ul元素的子元素,在控制台中的输出结果为HTMLCollection(4) [li, li, li, li]。

(3) 获取子节点

firstChild属性和lastChild属性,前者返回第一个子节点,后者返回的是最后一个子节点,如果找不到则返回null。需要注意的是它们的返回值包括文本节点和元素节点等。

(4) 获取子元素节点

firstElementChild属性和lastElementChild属性,前者返回第一个子元素节点,后者返回最后一个子元素节点,如果找不到则返回null。需要注意的是,这两个属性有兼容性问题,IE 9以上才支持。

实际开发中,firstChild 和lastChild 包含其他节点,操作不方便;而firstElementChild和lastElementChild又有兼容性问题,那么如何获取第一个子元素节点或最后一个子元素节点呢?为了解决兼容性问题,在实际开发中通常使用“obj.children[索引] ”的方式来获取子元素节点。示例代码如下。

obj.children[0]             // 获取第一个子元素节点

obj.children[obj.children.length - 1]  // 获取最后一个子元素节点

3. 获取兄弟节点

在JavaScript中,可以使用nextSibling属性来获得下一个兄弟节点,使用previousSibling属性来获得上一个兄弟节点。它们的返回值包含元素节点或者文本节点等。如果找不到,就返回null。

如果想要获得兄弟元素节点,则可以使用nextElementSibling返回当前元素的下一个兄弟元素节点,使用previousElementSibling属性返回当前元素的上一个兄弟元素节点。如果找不到则返回null。要注意的是,这两个属性有兼容性问题,IE 9以上才支持。

实际开发中,nextSibling和previousSibling属性返回值都包含其他节点,操作不方便,而nextElementSibling和previousElementSibling又有兼容性问题。为了解决兼容性问题,在实际开发中通常使用封装函数来处理兼容性。示例代码如下。

 1  function getNextElementSibling(element) {

 2   var el = element;

 3   while (el = el.nextSibling) {

 4    if (el.nodeType === 1) {

 5     return el;

 6    }

 7   }

 8   return null;

 9  }

上述代码中,第1行代码定义了getNextElementSibling()函数,参数为element。在while循环中,通过if条件语句进行判断,如果nodeType属性值等于1,那么获取到的节点类型为元素节点。

点击此处
隐藏目录