节点操作

节点概述

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中节点使用 node 来表示。HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除

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

  • 元素节点 nodeType 为 1
  • 属性节点 nodeType 为 2
  • 文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)

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

节点层级

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

父级节点

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

子节点

//返回所有的子元素节点
parentNode.children

//返回第一个子元素节点,找不到则返回null,IE9以上支持
parentNode.firstElementChild

//返回最后一个子元素节点,找不到则返回null,IE9以上支持
parentNode.lastElementChild
  • parentNode.children 是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回 (这个是我们重点掌握的)。
  • 如果想要第一个子元素节点,可以使用 parentNode.chilren[0]
  • 如果想要最后一个子元素节点,可以使用parentNode.chilren[parentNode.chilren.length - 1]

兄弟节点

node.nextSibling

node.previousSibling
  • nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null,包含所有的节点。
  • previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
 node.nextElementSibling 

 node.previousElementSibling 

  • nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null。
  • previousElementSibling 返回当前元素上一个兄弟元素节点,找不到则返回null
  • 注意:这两个方法有兼容性问题, IE9 以上才支持。

如何解决兼容性问题 ?

 function getNextElementSibling(element) {
     var el = element;
     while (el = el.nextSibling) {
     	if (el.nodeType === 1) {
   			  return el;
        }
     }
     return null;
 }	

节点操作

创建节点

 document.createElement('tagName')

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

三种动态创建元素区别

  • document.write()
  • element.innerHTML
  • document.createElement()

区别

  1. document.write 是直接将内容写入页面的内容流,此时文档流执行完毕,它会导致页面全部重绘,相同与创建了一个只包含写入内容的新页面

  2. innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘

  3. innerHTML 创建多个元素效率更高,但是采用拼接字符串方式效率低,原因是字符串的不可变性,拼接会不断开辟新空间,采取数组形式效率高

  4. createElement() 创建多个元素效率稍低一点点,但是结构更清晰

//数组方式,效率最高
  for (var i = 0; i < 1000; i++) {
            array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
        }
        document.body.innerHTML = array.join('');

//拼接字符串方式,效率低
 var str = '';
        for (var i = 0; i < 1000; i++) {
            document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
        }

//createElement() ,略低于数组方式
for (var i = 0; i < 1000; i++) {
            var div = document.createElement('div');
            div.style.width = '100px';
            div.style.height = '2px';
            div.style.border = '1px solid red';
            document.body.appendChild(div);
        }

添加节点

 node.appendChild(child)

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

 node.insertBefore(child, 指定元素)

将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before 伪元素。

案例:留言板

<style>
        * {
            margin: 0;
            padding: 0;
        }
        
        body {
            padding: 100px;
        }
        
        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid pink;
            outline: none;
            resize: none;
        }
        
        ul {
            margin-top: 50px;
        }
        
        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(245, 209, 243);
            color: red;
            font-size: 14px;
            margin: 15px 0;
        }
    </style>
</head>

<body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>

    </ul>
    <script>
        // 1. 获取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2. 注册事件
        btn.onclick = function() {
            if (text.value == '') {
                alert('您没有输入内容');
                return false;
            } else {
                // console.log(text.value);
                // (1) 创建元素
                var li = document.createElement('li');
                // 先有li 才能赋值
                li.innerHTML = text.value;
                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
            }
        }
    </script>
</body>

案例分析:

① 点击按钮之后,就动态创建一个li,添加到ul 里面。

② 创建li 的同时,把文本域里面的值通过li.innerHTML 赋值给 li

③ 如果想要新的留言后面显示就用 appendChild 如果想要前面显示就insertBefore

删除节点

 node.removeChild(child)

从 DOM 中删除一个子节点,并返回删除的节点。

posted @ 2021-07-06 23:41  至安  阅读(230)  评论(0编辑  收藏  举报