DOM-节点操作

752 阅读4分钟

目录

一.学习节点操作目的

二.节点概述

三.节点层级

四.创建添加节点

五.删除节点

六.克隆节点


一.学习节点操作目的

我们为什么学习节点操作?学习节点操作的目的是为了获取元素

在学习节点操作之前,我们已经学习了利用DOM提供的方法获取元素。

如document.getElementById,document.getElementsByClassName 等等 但它存在着逻辑性不强,繁琐的缺点。

我们利用节点层级关系获得元素,逻辑性会更强,操作相对于前者也会更加简单,但也存在着兼容性稍差的缺点。

二.节点概述

在网页中所有内容均为节点(标签,属性,文本,注释等),在DOM中节点用node表示。

HTML DOM树中所有节点均可以通过JavaScript进行访问,所有HTML元素(节点)均可以被修改,创建,或删除。

DOM树:

节点操作思维导图.png

一般的节点至少拥有nodeType(节点类型),nodeName(节点名称),nodeValue(节点值),这三个基本属性。

  • 元素节点nodeType为1(元素节点包括如body,div这样的标签,皆是元素节点)
  • 属性节点nodeType为2 (如class="box",这样的属性称为属性节点)
  • 文本节点nodeType为3(文本节点包括文字,空格,换行等)

在我们的实际开发中,节点操作的主要是元素节点

三.节点层级

利用DOM树可以把节点划分为不同层级关系,常见的是父子兄层级关系

1.父级节点

node.parentNode
  • parentNode可以返回某节点的父级节点,注意是最近的一个父级节点
  • 如果指定的节点没有父级节点,就返回null

代码演示

<div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
</div>
<script>
        // 1.父节点 parentNode
        var erweima = document.querySelector('.erweima');
        // 得到离元素最近的父级节点
        console.log(erweima.parentNode);    //就可以得到box 
</script>

2.子级节点

(1)parentNode.childNodes,返回包含指定节点子节点的集合,该集合为及时更新的集合。

parentNode.childNodes(标准)

注意:返回值里包含了所有节点,元素节点,文本节点,等等,如果想要单纯获得元素节点,则需要做其他处理,所以我们一般不提倡用parentNode,childNodes获取子节点。

(2)parentNode.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其他元素不返回。(children虽然是非标准的,但得到所有浏览器的支持,没有兼容性的问题)

parentNode.children

(1)(2)代码演示

<body>
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>

    <ol>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ol>

    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>

    <script>
        // DOM提供的方法(API)获取
        var ul = document.querySelector('ul');
        var lis = document.querySelectorAll('li');
        // 1.子节点 childNode包括所有子节点 文本节点 元素节点 等等 (所以我们一般不使用)
        console.log(ul.childNodes);        //html(9)  因为他们之间是有换行的 换行属于文本节点
        console.log(ul.childNodes[0].nodeType);
        console.log(ul.childNodes[1].nodeType);
        // 2.children获取所有的子元素节点  非正式 较常用
        console.log(ul.children);
    </script>
</body>

(3)parentNode.firstChild返回第一个子节点,没有则返回null,同样也是包含所有节点

parentNode.firstChild

(4)parentNode.lastChild返回第一个子节点,没有则返回null,同样也是包含所有节点

parentNode.lastChild

(5)parentNode.firstElementChild返回第一个子元素节点,没有则返回null

parentNode.firstElementChild

(6)parentNode.lastElementChild返回第一个子元素节点,没有则返回null

parentNode.lastElementChild

注意:(5) (6)两种方法虽可以直接获得第一个与最后一个子元素节点,但也存在兼容性的问题,只有ie9以上才支持。

(4)~(6)代码演示:

<body>
    <ol>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ol>

    <script>
        // 获取第一个子元素与最后一个子元素
        var ol = document.querySelector('ol');
        // 1.firstChild第一个节点 不管是文本节点还是元素节点
        console.log(ol.firstChild);
        console.log(ol.lastChild);
        // 2.firstElmentChild返回第一个子元素节点   但这个存在兼容性的问题
        console.log(ol.firstElementChild);
        console.log(ol.lastElementChild);
    </script>
</body>

在实际开发中firstChild,lastChild只能获取第一个子节点,而firstElementChild,lastElementChild有存在兼容性的问题,那有什么方法可以解决呢?

解决方案:如果想要第一个子元素节点,可以使用parentNode.children[0]

// 3.实际开发的写法 既没有兼容性的问题 又返回第一个元素
        console.log(ol.children[0]);
        console.log(ol.children[ol.children.length - 1]);

3.兄弟节点

(1)nextSibling 返回下一个兄弟节点 包含元素节点或者文本节点,找不到则返回null

node.nextSibling

(2)previousSibling 返回上一个兄弟节点 包含元素节点或者文本节点,找不到则返回null

node.previousSibling

(3)nextElementSibling 返回下一个兄弟元素节点,找不到则返回null,存在兼容性问题

node.nextElementSibling

(4)previousElementSibling 返回上一个兄弟元素节点 ,找不到则返回null,存在兼容性问题

node.previousElementSibling

注意:如果想解决兼容性问题需要自己封装一个函数

(1)~(4)代码演示

<body>
    <div>1</div>
    <span>2</span>
    <script>
        var div = document.querySelector('div');
        // 1.nextSibling 下一个元素节点 包含元素节点或者文本节点
        console.log(div.nextSibling);
        console.log(div.previousSibling);
        // 2.nextElementSibling 获取下一个元素节点
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);     //没有的话就是null
    </script>
</body>

四.创建添加节点

1.创建节点

document.createElement();方法创建由tagName指定的HTML元素,因为这些元素不存在,是根据我们的需求动态生成的,所以也称为动态创建元素节点

document.createElement('tagName');

2.添加节点

(1)node.appendChild()方法将一个指定节点添加到父节点的子节点列表末尾,类似于css里面的:after伪元素。

node.appendChild()

(2)node.insertBefore()方法是将一个节点添加到父节点的指定子节点的前面,类似与css里面的:before伪元素。

node.insertBefore(child,指定元素)

代码演示

<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        // 1.创建节点元素
        var li = document.createElement('li');
        // 2.添加节点 node.appendChild(child);  node是父级 child是子级 后面追加元素 类似于数组中的push
        // (1)先获取父级元素小li 
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        // 3.添加节点 insertBefore(child,指定元素)    指定元素就是要加在它前面的元素
        var lili = document.createElement('li');    //括号里面要填创建的元素类型
        ul.insertBefore(lili, ul.children[0]);   //在第一个li的前面插入lili
        // 4.我们想在页面中添加一个元素分两步 1.创建元素 2.添加元素
    </script>
</body>

五.删除节点

node.removeChild()方法从DOM中删除一个子节点,返回删除节点

node.removeChild()

代码演示

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <button>删除</button>
    <script>
        // 1.获取元素
        var btn = document.querySelector('button');
        var ul = document.querySelector('ul');
        // 2.删除元素 node.removeChild(child);
        // ul.removeChild(ul.children[0]);
        // 3.点击按钮依次删除里面的孩子
        btn.onclick = function () {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>

六.克隆节点

node.cloneNode()返回点用该方法元素节点的一个副本,也称为克隆节点或拷贝节点

node.cloneNode()

注意

1.node.cloneNode() 如果括号为空或者括号里面为false则为浅拷贝· 浅拷贝只复制标签 不复制标签里面的内容

2.node.cloneNode(true) 括号里面为true则为深拷贝 深拷贝复制标签与标签里面的内容

代码演示

<body>
    <ul>
        <li>11111</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        var lili = ul.children[0].cloneNode('true');
        ul.appendChild(lili);

    </script>
</body>