2022年7月20日 周三学习记录博客 学习时长:3.5h 学习内容:DOM操作中的节点操作
目录
练习案例代码下载:https://download.youkuaiyun.com/download/MartinYP/86246800
DOM操作元素——H5自定义属性(上篇博客补充)
操作元素案例:tab 栏切换(重点)
当鼠标点击上面相应的选项卡(tab),下面内容跟随变化
分析
- Tab栏切换有2个大的模块
- 上的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想) 修改类名的方式
- 下面的模块内容,会跟随上面的选项卡变化。所以下面模块变化写到点击事件里面。
- 规律:下面的模块显示内容和上面的选项卡一一对应,相匹配。
- 核心思路: 给上面的tab_list 里面的所有小li 添加自定义属性,属性值从0开始编号。
- 当我们点击tab_list 里面的某个小li,让tab_con 里面对应序号的 内容显示,其余隐藏(排他思想)
JS代码:
<script>
// 获取元素
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
var items = document.querySelectorAll('.item');
// for循环绑定点击事件
for (var i = 0; i < lis.length; i++) {
// 开始给5个小li 设置索引号
lis[i].setAttribute('index', i);
lis[i].onclick = function() {
// 1. 上的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想) 修改类名的方式
// 其余的li清除 class 这个类
for (var i = 0; i < lis.length; i++) {
lis[i].className = '';
}
// 留下自己模块
this.className = 'current';
// 2. 下面的显示内容模块
var index = this.getAttribute('index');
console.log(index);
// 让其余的item div 隐藏
for (var i = 0; i < items.length; i++) {
items[i].style.display = 'none';
}
// 留下自己模块 让对应的item 显示出来
items[index].style.display = 'block';
}
}
</script>
4.7 H5自定义属性
自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
自定义属性获取是通过getAttribute(‘属性’) 获取。
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
所以H5新增了自定义属性
1.设置H5自定义属性
H5规定自定义属性data-开头做为属性名并且赋值。
比如 <div data-index = "1"></div>
或者使用 JS 设置
element.setAttribute(‘data-index’, 2)
2.获取H5自定义属性
兼容性获取 element.getAttribute(‘data-index’);
H5新增 element.dataset.index 或者 element.dataset[‘index’] ie 11才开始支持
节点操作
1 为什么使用节点操作
获取元素通常使用两种方式:
5.2 节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
- 元素节点 nodeType 为 1
- 属性节点 nodeType 为 2
- 文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)
我们在实际开发中,节点操作主要操作的是元素节点
5.3 节点层级
利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。
1. 父级节点
parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
如果指定的节点没有父节点则返回 null
2.子节点
parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。
注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等。
如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes
<scirpt>
0var ul = document. querySelector(‘ul’);
for(var i = 0; i < ul.childNodes.length;i++) {
if (ul.childNodes[i].nodeType == 1) {
// ul.childNodes[i] 是元素节点
console.log(ul.childNodes[i]);
}
}
</scirpt>
parentNode.children 是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回 (需要重点掌握)。
虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用
firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。
lastChild 返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。
firstElementChild 返回第一个子元素节点,找不到则返回null。
lastElementChild 返回最后一个子元素节点,找不到则返回null。
实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?
解决方案:
如果想要第一个子元素节点,可以使用 parentNode.chilren[0]
如果想要最后一个子元素节点,可以使用 parentNode.chilren[parentNode.chilren.length - 1]
案例:下拉菜单
分析
- 导航栏里面的li 都要有鼠标经过效果,所以需要循环注册鼠标事件
- 核心原理: 当鼠标经过li 里面的 第二个孩子 ul 显示, 当鼠标离开,则ul 隐藏
JS代码展示
<script>
// 1. 获取元素
var nav = document.querySelector('.nav');
var lis = nav.children; // 得到4个小li
// 2.循环注册事件
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>
3. 兄弟节点
nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null。
previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回null。
注意:方法3、4 IE9以上才支持
问:如何解决兼容性问题 ?
答:自己封装一个兼容性的函数
4 创建节点
document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。
5 添加节点
node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的 after 伪元素。
node.insertBefore() 方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before 伪元素。
案例:简单版发布留言案例
分析:
- 核心思路: 点击按钮之后,就动态创建一个li,添加到ul 里面。
- 创建li 的同时,把文本域里面的值通过li.innerHTML 赋值给 li
- 如果想要新的留言后面显示就用 appendChild 如果想要前面显示就用insertBefore
6 删除节点
node.removeChild() 方法从 DOM 中删除一个子节点,返回删除的节点。