DOM--1 document对象-遍历节点/元素节点树

498 阅读5分钟

讲DOM之前,说说对象分类

首先JS对象其实目前有好几种分法,但是主流分法中不管是哪一种,DOM都常被认为是宿主对象。其中一种分法就是将JS对象分为三种: 内部对象、宿主对象、自定义对象 内部对象:Array、Boolean、Date、Function、Global、Math、Error.... 宿主对象:运行JS脚本环境提供的对象,包含window、document、FormDate、XMLHttpRequest... 自定义对象:就是自己定义的对象 首先window对应着BOM对象相关的知识,document对应着DOM相关的知识,DOM是文档对象模型。但是其实DOM是隶属于BOM的,只是我们经常把DOM专门拿出来说

document方法

首先document是一个对象,从JS的角度来说它代表了一个文档本身,他是所有文档节点的最顶端 那么document上既然是对象就会有相关的方法和属性,我们这一节主要说它的方法。

getElementById/getElementByTagName等

1. document.getElementById('box');//在IE8及以下是不分大小写的,而且在IE8及以下你元素上如果设置了name特性也为box,没有id特性,用该方法是拿得到的
2. document.getElementsByClassName('box1');//IE8及以下用不了
3. document.getElementByTagName('div')//兼容性很好,都兼容
4. document.getElementByName();//用得非常少

首先说明,像id特性能不设置就不要设置,模块化开发时id常用于后端向前端注入数据,id一般在前端中叫做钩子 这些方法中,只有getElementById()返回的是元素,其他的方法返回的都是类数组

querySelector/querySelectorAll

这是HTML5规范中新写入的WEB API(但其实很早以前就有了,只是没纳入规范,早有所以兼容性很好)

var div1 = document.querySelector('div');
var div2 = document.querySelector('.text');
var div3 = document.querySelector('div p');
var div4 = document.querySelector('div > p');
var div5 = document.querySelector('#box');

我们从使用方法上可以看出()中的选择元素的写法是和css选择器一样的,而且这个方法如果选择到多个元素只会返回选择到的第一个元素

如果我们想获得多个元素可以选择使用document.querySelectorAll var div1 = document.querySelectorAll('.box'); 这样会返回一个包含元素节点的类数组,即使你想获取的是有id特性的元素,也是返回类数组 那么这两个方法兼容性那么好,选择方法还和css很像,那为啥我们很少用这个方法,因为有两个缺点:

1. 性能不好

2. 不是实时的,或者说不是返回值是静态的一旦初始值确定就不会改变

例如:

var divs = document.querySelectorAll('div');
console.log(divs);//[div, div, div]
divs[0].remove();
console.log(divs);//[div, div, div]  不是实时的

元素节点树

元素节点树.png 首先值得注意的是:节点树并不等于元素节点树,而是包含元素节点树 访问节点document上有方法(兼容性比较好),访问元素节点document也有单独的方法。

访问节点(所有节点类型)的属性

访问节点的方法常用的有parentNode/childNodes、firstChild/lastChild、 previousSibling/nextSibling

parentNode(父节点)

在编辑器中写相应代码:

<ul>
    <li>
        <h2>我是标题标签</h2>
        <a href="">我是超链接标签</a>
        <p>我是段落标签</p>
     </li>
 </ul>
var a=document.getElementsByTageName('a')[0];

在浏览器控制台输入如下代码会得到如下结果:

parentNode1.png parentNode2.png

从以下现象中可以看出,document就是所有文档节点的最顶端

childNodes(子节点)

在编辑器中写相应代码:

<ul>
    <li>
        <!--这是个注释-->
        <h2>我是标题标签</h2>
        <a href="">我是超链接标签</a>
        <p>我是段落标签</p>
     </li>
 </ul>
var li=document.getElementsByTageName('li')[0];
console.log(li.childNodes.length);

控制台输出结果为:

childNode结果.png

这也侧面说明了节点不仅仅是只有元素节点,也有其他节点 其中节点类型可以用数字来表示: 1.元素节点 === 1 2.属性节点 === 2 3.文本节点(text) === 3 4.注释节点(comment) === 8 5.document === 9 6.DocumentFragment === 11

firstChild/lastChild(第一个/最后一个节点)

还是上面的HTML代码,然后js代码如下:

var li = document.getElementsByTagName('li')[0];
console.log(li.lastChild); //#text

元素内第一个节点/元素内最后一个节点 原理与上方一致

nextSibling/previousSibing

var p=document.getElementsByTageName('p')[0];
console.log(p.previousSibling);//#text

元素自身的上一个节点/元素的下一个节点 原理与上方一致

获取元素节点的属性

获取元素节点的属性一般有:parentElement/children、 firstElementChild/lastElementChild、nextElementSibing/previousElementSibing

parentElement(父元素节点,IE9及以下不支持)

文档中的元素节点的顶端是html元素

parentElement.png

children(子元素节点,IE7及以下不支持)

<div class="div1">
    <p>这是第一个p标签</p>
    <p class="div2">这是第二个p标签</p>
    <span>这是一个span</span>
</div>
    var div1 = document.getElementsByClassName('div1')[0];
    console.log(div1.children);

结果为: children结果.png

firstElementChild/lastElementChild(IE9及以下不支持)

还是前面的HTML代码,为了查看firstElementChild, js修改代码如下:

    var div1 = document.getElementsByClassName('div1')[0];
    console.log(div1.firstElementChild);

结果是:

firstElementChild.png

还是前面的HTML代码,为了查看lastElementChild, js修改代码如下:

    var div1 = document.getElementsByClassName('div1')[0];
    console.log(div1.lastElementChild);

结果是:

firstElementChild2.png

nextElementSibling/previousElementSibling(IE9及以下不支持)

还是前面的HTML代码,为了查看nextElementSibling, js修改代码如下:

    var p = document.getElementsByClassName('p2')[0];
    console.log(p.nextElementSibling);

结果如下: nextElementSibling.png

还是前面的HTML代码,为了查看previousElementSibling, js修改代码如下:

    var p = document.getElementsByClassName('p2')[0];
    console.log(p.previousElementSibling);

结果如下:

previousSibling.png

简要总结 DOM是文档对象模型,是JS对象中的宿主对象,DOM与document相关,document常见的相关方法有 document.getElementById、document.getElementsByClassName、 document.getElementsByTagName、document.getElementsByName

  1. document.getElementById方法括号内获取元素的元素名在IE8及以下是不分大小写的,而且在IE8及以下你元素上如果设置了name特性也为box,没有id特性,用该方法是拿得到的。
  2. document.getElementsByClassName方法IE8及以下用不了
  3. document.getElementByTagName兼容性很好,都兼容
  4. document.getElementByName用得非常少

节点包含元素节点与其他节点,获取各种类型节点的属性有parentNode/childNodes、firstChild/lastChild、nextSibling/previousSibling,兼容性都很好 获取元素节点的属性有parentElement(IE9及以下不支持)、children(IE7及以下不支持)、 firstElementChild/lastElementChild(IE9及以下不支持)、nextElementSibing/previousElementSibing(IE9及以下不支持)