5 节点操作
5.1 为什么学习节点操作
5.2 节点概述
一般情况下,节点至少拥有节点类型(nodeType)、节点名称(nodeName)、节点值(nodeValue)这三个基本属性
<body> <!-- 节点的优点 --> <div>我是div</div> <span>我是span</span> <ul> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ul> <div class="box"> <span class="erweima">x</span> </div> <script> var box = document.querySelector('.box'); console.dir(box); //可以通过这个方式查看节点的属性 </script> </body>
查看部分属性:
- 元素节点的nodeType为1(常用)
- 属性节点的nodeType为2
- 文本节点的nodeType为3(包含文字空格换行等)
5.3 节点层级
父级节点
node.parentNode
<body> <!-- 节点的优点 --> <div>我是div</div> <span>我是span</span> <ul> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ul> <div class="demo"> <div class="box"> <span class="erweima">x</span> </div> </div> <script> //获取box和erweima这两个盒子 //过去的做法 // var erweima = document.querySelector('.erwima'); // var box = document.querySelector('.box'); //1. 父节点parentNode 现在的做法 var erweima = document.querySelector('.erweima'); console.log(erweima.parentNode); //得到的是距离元素erweima最近的父级节点box,如果找不到其父节点就返回为null </script> </body>
子节点
- 标准:
parentNode.childNodes
<body> <!-- 节点的优点 --> <div>我是div</div> <span>我是span</span> <ul> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ul> <ol> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ol> <div class="demo"> <div class="box"> <span class="erweima"></span> </div> </div> <script> //获取ul里面的li //过去的方法 var ul = document.querySelector('ul'); var lis = ul.querySelectorAll('li'); //现在的方法 //1. 子节点 返回包含指定节点的字节的的集合,该集合为即时更新的集合 console.log(ul.childNodes); //NodeList(9) [text, li, text, li, text, li, text, li, text] 返回值里包含了所有的节点包括元素节点、文本节点等 中间有5个换行,所以有5个文本节点text console.log(ul.childNodes[0].nodeType); //3 文本节点的nodeType的属性是3 console.log(ul.childNodes[1].nodeType); //1 元素节点的nodeType的属性是1 //为了获得其中的元素节点需要专门处理(所以一般不提倡用childNodes) for (var i = 0; i < ul.childNodes.length; i++) { if (ul.childNodes[i].nodeType == 1) { console.log(ul.childNodes[i]); } } </script> </body>
- 非标准:
parentNode.children//可以得到所有的子元素节点 是一个只读属性 返回一个伪数组
<body> <!-- 节点的优点 --> <div>我是div</div> <span>我是span</span> <ul> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ul> <ol> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ol> <div class="demo"> <div class="box"> <span class="erweima"></span> </div> </div> <script> //获取ul里面的li //过去的方法 var ul = document.querySelector('ul'); var lis = ul.querySelectorAll('li'); //现在的方法 //1. 子节点 返回包含指定节点的字节的的集合,该集合为即时更新的集合 console.log(ul.childNodes); //NodeList(9) [text, li, text, li, text, li, text, li, text] 返回值里包含了所有的节点包括元素节点、文本节点等 中间有5个换行,所以有5个文本节点text console.log(ul.childNodes[0].nodeType); //3 文本节点的nodeType的属性是3 console.log(ul.childNodes[1].nodeType); //1 元素节点的nodeType的属性是1 //为了获得其中的元素节点需要专门处理(所以一般不提倡用childNodes) for (var i = 0; i < ul.childNodes.length; i++) { if (ul.childNodes[i].nodeType == 1) { console.log(ul.childNodes[i]); } } //2. 获取所有的子元素节点 console.log(ul.children); //HTMLCollection(4) [li, li, li, li] </script> </body>
子节点的相关操作:获取第一个子元素和最后一个子元素
parentNode.firstChild //返回第一个子节点,找不到则返回null。同样也是包含所有的节点
parentNode.lastChild //返回最后一个子节点,找不到则返回null。同样也是包含所有的节点
parentNode.firstElementChild //返回第一个子节点,找不到则返回null。只包含元素节点
parentNode.lastElementChild //返回最后一个子节点,找不到则返回null。只包含元素节点
注意:后两个方法有兼容性问题,ie9以上才支持
<body> <ol> <li>我是li1</li> <li>我是li2</li> <li>我是li3</li> <li>我是li4</li> </ol> <script> var ol = document.querySelector('ol'); //1. 不仅仅包含元素节点 console.log(ol.firstChild); //#text 文本节点 console.log(ol.lastChild); //#text 文本节点 //2. 兼容新问题 console.log(ol.firstElementChild); //<li>我是li1</li> console.log(ol.lastElementChild); //<li>我是li4</li> //3. 实际开发 既没有兼容性问题又返回第一个子元素 console.log(ol.children[0]); //<li>我是li1</li> console.log(ol.children[ol.children.length - 1]); //<li>我是li4</li> </script> </body>
案例:下拉菜单
- 导航栏里面的li都要有鼠标经过的效果,所以需要循环注册鼠标事件
- 核心原理:当鼠标经过li里面的第二个孩子(ul)显示,当鼠标离开,则ul隐藏。
<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>...</li> <li>...</li> <li>...</li> </ul> <script> //1. 获取元素 var nav = document.querySelector('.nav'); var lis = nav.querySelectorAll('li'); //得到4个小li //2. 循环注册事件 for (var i = 0; i < lis.length - 1; i++) { lis[i].onmouseover = function() { this.children[1].style.display = 'block'; } lis[i].onmouseout = function() { this.children[1].style.display = 'none'; } } </script> </body>
样式内容省略
兄弟节点
<body> <div>我是div</div> <span>我是span</span> <script> var div = document.querySelector('div'); //1. node.nextSibling 返回当前元素的下一个兄弟节点,找不到则返回null。包含所有节点 console.log(div.nextSibling); //#text //2. node.previousSibling 返回当前元素的上一个兄弟节点,找不到则返回null。包含所有节点 console.log(div.previousSibling); //#text //3. node.nextElementSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。 console.log(div.nextElementSibling); //<span>我是span</span> //4. node.previousElementSibling 返回当前元素的上一个兄弟元素节点,找不到则返回null。 console.log(div.previousElementSibling); //null 因为div上面没有兄弟了 //后两个方法依然有兼容性问题,ie9以上才支持 //解决方法:自己封装一个函数(了解) function getnextElementSibling(element){ var el = element; while(el = el.nextSibling) { if(el.nodeType == 1) { return el; } } return null; } </script> </body>
5.4 创建节点 和添加节点
- 创建
document.creatElement('tagName')
document.creatElement()方法创建由tagName指定的HTML元素。因为这些元素原先不存在,是我们根据需求动态生成的,所以我们也称为动态创建元素节点。
- 添加
node.appendChild(child)
node.appendChild()方法将一个节点添加到指定父节点的子节点列表的末尾。类似于css元素里的after伪元素。
node.insertBefore(child,指定元素)
node.insertBefore()方法将一个节点添加到父节点指定子节点前面。类似于css里面的before伪元素
<body> <ul> <li>123</li> </ul> <script> //在ul里动态地再创建一个li //1. 创建元素节点 var li = document.createElement('li'); //2. 添加节点 node.appendChild(child) node是父级 child是子级 在后面追加元素 var ul = document.querySelector('ul'); ul.appendChild(li); //1. 创建元素节点 var lili = document.createElement('li'); //3. 添加节点node.insertBefore(child,指定元素) ul.insertBefore(lili, ul.children[0]); </script> </body>
案例:简单版发布留言案例
- 思路: 当点击按钮之后就动态创建一个li,之后再把li创建到ul之中就可以了
- 在创建li的同时,把文本域里面的值通过li.innerHTML赋值给li
- 如果想要新的留言后面显示就用appendChild,如果想要前面显示就用insertBefore
<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 { //(1)创建元素 var li = document.createElement('li'); //给li赋值 li.innerHTML = text.value; //(2)添加元素 // ul.appendChild(li);新留言在最后 ul.insertBefore(li, ul.children[0]); } } </script> </body>
样式省略
来源:https://www.cnblogs.com/deer-cen/p/12237812.html