JavaScript DOM–节点操作
节点
节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
- 元素节点 nodeType 为1
- 属性节点 nodeType 为2
- 文本节点 nodeType 为3 (文本节点包含文字,空格和换行)
一般我们开发操作的是元素节点
节点层级
父级节点
node.parentNode
- 返回离自己最近的那个父亲
- 没有父亲,就返回null
<body> <div class="demo"> <div class="box"> <span class="erweima">×</span> </div> </div> <script> var erweima = document.querySelector('.erweima'); console.log(erweima.parentNode); // 父节点 </script> </body>
子节点
- 所有节点
node.childNodes
- 返回子节点的集合
- 返回的节点包含了所有的子节点,包括元素节点,文本节点
- 子元素节点
node.children
- 返回的是一个只读节点
<body> <ul> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ul> <script> var ul = document.querySelector('ul'); // childNodes console.log(ul.childNodes); // NodeList(9) [text, li, text, li, text, li, text, li, text] console.log(ul.childNodes[0].nodeType); // 3 // children console.log(ul.children); // HTMLCollection(4) [li, li, li, li] </script> </body>
- 第一个子节点
parentNode.firstChild
- 找到返回第一个子节点,找不到返回null
- 最后一个节点
parentNode.lastChild
- 找到返回最后一个节点,找不到返回null
- 第一个元素节点
parentNode.firstElementChild
- 找到返回第一个元素节点,找不到返回null
- 最后一个元素节点
parentNode.lastElementChild
- 找到返回最后一个元素节点,找不到返回null
兄弟节点
- 下一个兄弟节点
找不到返回null
node.nextSibling
- 上一个兄弟节点
找不到返回null
node.previousSibling
- 下一个兄弟元素节点(兼容性问题)
找不到返回null
node.nextElementSibling
- 上一个兄弟元素节点(兼容性问题)
找不到返回null
node.previousElementSibling
<body> <div>我是div</div> <span>我是span</span> <script> var div = document.querySelector('div'); // 1. nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等 console.log(div.nextSibling); // #text // 2. nextElementSibling 得到下一个兄弟元素节点 console.log(div.nextElementSibling); </script> </body>
操作节点
添加节点
- 添加到节点列表末尾
node.appendChild(child)
- 添加到指定节点前面
node.insertBefore(child, 指定元素)
<body> <ul> <li>123</li> </ul> <script> var ul = document.querySelector('ul'); // 创建节点 var li = document.createElement('li'); li.innerHTML = '<li>appendChild</li>'; // 添加节点 appendChild ul.appendChild(li); // 插入节点 var lili = document.createElement('li'); lili.innerHTML = '<li>insertBefore</li>'; ul.insertBefore(lili, ul.children[0]) </script> </body>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { margin: 0; padding: 0; } li { list-style-type: none; } a { text-decoration: none; font-size: 14px; } .nav { margin: 100px; } .nav>li { position: relative; float: left; width: 80px; height: 41px; text-align: center; } .nav li a { display: block; width: 100%; height: 100%; line-height: 41px; color: #333; } .nav>li>a:hover { background-color: #eee; } .nav ul { display: none; position: absolute; top: 41px; left: 0; width: 100%; border-left: 1px solid #FECC5B; border-right: 1px solid #FECC5B; } .nav ul li { border-bottom: 1px solid #FECC5B; } .nav ul li a:hover { background-color: #FFF5DA; } </style> </head> <body> <ul class="nav"> <li> <a href="#">微博</a> <ul> <li> <a href="">私信</a> </li> <li> <a href="">评论</a> </li> <li> <a href="">@我</a> </li> </ul> </li> <li> <a href="#">微博</a> <ul> <li> <a href="">私信</a> </li> <li> <a href="">评论</a> </li> <li> <a href="">@我</a> </li> </ul> </li> <li> <a href="#">微博</a> <ul> <li> <a href="">私信</a> </li> <li> <a href="">评论</a> </li> <li> <a href="">@我</a> </li> </ul> </li> <li> <a href="#">微博</a> <ul> <li> <a href="">私信</a> </li> <li> <a href="">评论</a> </li> <li> <a href="">@我</a> </li> </ul> </li> </ul> <script> var nav = document.querySelector('.nav'); var lis = nav.children; for (var i = 0; i < lis.length; i++) { lis[i].onmouseover = function () { this.children[1].style.display = 'block'; }; lis[i].onmouseout = function () { this.children[1].style.display = 'none'; } } </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <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> // 获取元素 var button = document.querySelector('button'); var text = document.querySelector('textarea'); var ul = document.querySelector('ul'); // 注册事件 button.onclick = function () { // 获取文本框的值 if (text.value == '') { alert('请输入值'); return false } else { // 创建节点 var li = document.createElement('li'); // 给节点赋值 li.innerHTML = text.value; // 插入到最前面 ul.insertBefore(li, ul.children[0]); } } </script> </body> </html>
删除节点
删除一个子节点,返回删除的节点
node.removeChild()
<body> <button>删除</button> <ul> <li>熊大</li> <li>熊二</li> <li>光头强</li> </ul> <script> // 获取元素 var button = document.querySelector('button'); var ul = document.querySelector('ul'); button.onclick = function () { if (ul.children.length == 0){ this.disabled = true // 禁止按钮 } else { // 删除第一个 ul.removeChild(ul.children[0]) } } </script> </body>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <textarea name="" id=""></textarea> <button>发布</button> <ul> </ul> <script> // 获取元素 var text = document.querySelector('textarea'); var button = document.querySelector('button'); var ul = document.querySelector('ul'); // 注册事件 button.onclick = function () { if (text.value == '') { alert('输入内容'); return false } else { // 添加元素和删除按钮 var li = document.createElement('li'); li.innerHTML = text.value += "<a href='javascript:;'>删除</a>"; ul.insertBefore(li, ul.children[0]); // 给删除按钮a添加删除事件 var as = document.querySelectorAll('a'); for (var i=0; i<as.length; i++) { as[i].onclick = function () { ul.removeChild(this.parentNode); // 相对a而已,删除它的父亲 } } } text.value = '' // 清楚文本框内容 } </script> </body> </html>
克隆节点
- 返回节点的一个副本
- 参数为true为深拷贝
<body> <ul> <li>1111</li> <li>2</li> <li>3</li> </ul> <script> var ul = document.querySelector('ul'); // 拷贝 console.log(ul.cloneNode()); // <ul></ul> 浅拷贝 console.log(ul.cloneNode(true)); // 深拷贝 // 拷贝子节点 console.log(ul.children[0].cloneNode()); // <li></li> 浅拷贝 console.log(ul.children[0].cloneNode(true)); // 深拷贝 </script> </body>
创建节点
- document.write() 效率低
- ele.innerHTML 效率高
- document.createElement() 效率一般
区别
- document.write() 是直接将内容写入页面,整个页面执行完全部重新绘
- innerHTML 是将内容插入dom 节点 不会重新绘
- innerHTML 创建多个元素效率高
- createElement 创建多个元素效率低,但是结构清晰
<body> <button>创建</button> <div></div> <span></span> <script> var btn = document.querySelector('button'); // 1. write btn.onclick = function () { document.write('<div>123</div>') }; // 2.innerHTML var div = document.querySelector('div'); for (var i=0; i<= 100; i++) { div.innerHTML += '<a href="#">百度</a>' } // 3 createElement var span = document.querySelector('span'); for (var i=0; i<=100; i++) { var a = document.createElement('a'); span.appendChild(a); } </script> </body>