【DOM】DOM操作之如何修改元素的内容与属性_02
目录
回顾:DOM概述及DOM操作之如何查找元素_01
一. 修改: 3种东西
1. 元素的内容: 3种
(1). 获取或修改元素开始标签到结束标签之间的原始的HTML内容
(2). 获取或修改元素开始标签到结束标签之间的纯文本内容
(3). 获取或修改表单元素的值
2. 元素的属性: 3种
(1). 字符串类型的HTML标准属性
(2). bool类型的HTML标准属性
(3). 自定义扩展属性
⬛总结: DOM 5件事: 增删改查+事件绑定:
回顾:DOM概述及DOM操作之如何查找元素_01
一. 修改: 3种东西
1. 元素的内容: 3种
(1). 获取或修改元素开始标签到结束标签之间的原始的HTML内容
a. 元素.innerHTML
内部的html
b. 指的是原始HTML代码内容 包含html标签
(2). 获取或修改元素开始标签到结束标签之间的纯文本内容
a. 元素.textContent
文本 内容
b. 与 innerHTML 相比多做了两件事:
1). 去掉了内嵌的标签 不包含html标签
2). 将特殊符号翻译为正文
(3). 获取或修改表单元素的值
a. 问题: 大部分input表单元素都是单标记,没有结束标签,所以无法使用innerHTML和textContent
b. 解决: 今后,只要想获得表单元素的值,都用表单元素.value
(4). 示例: 比较三种内容属性的不同:
0_content.html
Document 来自<<新华社>>的消息
var p1 = document.getElementById("p1"); //想获取p元素的内容 console.log(p1.innerHTML); //想获得p元素的内容,但是想去掉内嵌的标签和特殊符号,只获取文字 console.log(p1.textContent); //想点击按钮,获得旁边文本框的内容 var btn = document.getElementById("btn"); btn.onclick = function () { //获得当前按钮的前一个兄弟input元素 var input = this.previousElementSibling; console.log(`查找 ${input.value} 相关的内容...`); };
运行结果:
(5). 示例: 动态开关门效果:
0_door.html
读取并修改元素的内容 div { float: left; height: 100px; line-height: 100px; } #d1, #d3 { background-color: #ccff00; } #d2 { cursor: pointer; background-color: #ffcc00; } 树形列表 << 内容的主体 //DOM 4步 //1. 查找触发事件的元素 //本例中: 用户点d2触发事件 var d2 = document.getElementById("d2"); //2. 绑定事件处理函数 d2.onclick = function () { //3. 查找要修改的元素 //本例中: 用户点d2,改的是d1 var d1 = document.getElementById("d1"); //4. 修改元素 //如果d2的内容是>>,说明d1是关着的! if (d2.innerHTML == ">>") { //就打开d1: 其实就是让d1显示出来,其实就是去掉d1的display属性 d1.style.display = ""; //等效于 //d2的内容变为<< d2.innerHTML = "<<"; } else { //否则如果d1是开着的 //就关闭d1: 其实就是让d1隐藏, 其实就是修改d1的display属性为none d1.style.display = "none"; //等效于: //d2的内容变为>> d2.innerHTML = ">>"; } };
运行结果:


2. 元素的属性: 3种
(1). 字符串类型的HTML标准属性
a. 什么是HTML标准属性: HTML标准中规定的属性
b. 如何获取或修改: 2种:
1). 旧核心DOM 4个函数:
i. 获取一个元素的一个属性值:
元素.getAttribute("属性名")
获取 属性
ii. 修改一个元素的属性值:
元素.setAttribute("属性名","属性值")
修改 属性
iii. 判断元素上是否包含某个属性
var bool值=元素.hasAttribute("属性名")
有 属性(吗)?
iv. 移除元素上一个属性
元素.removeAttribute("属性名")
移除 属性
v. 示例: 使用核心DOM4个函数操作元素的属性
1_attribute.html
Document go to tmooc var a1 = document.getElementById("a1"); //想获得a1的href属性值 var href = a1.getAttribute("href"); console.log(href); //修改a1的title属性值 a1.setAttribute("title", "Welcome tmooc"); //判断a1是否包含target属性 var bool = a1.hasAttribute("target"); console.log(bool); //false //移除a1的id属性 a1.removeAttribute("id"); console.log(a1);
运行结果:

vi. 问题: 旧核心DOM函数名太长,不好用!
2). 新HTML DOM:
i. 什么是HTML DOM: 是专门对常用的HTML对象和属性提供的简化版DOM
ii. 如何简化: HTML DOM已经提前将所有HTML标准属性都保存在了内存中的元素对象身上,只不过暂时不用的属性值,默认都为""。可以直接用.方式,访问对象中的标准属性。
iii. 示例: 使用新HTML DOM简化版属性实现和旧版核心DOM 相同的功能
1_attribute2.html
Document go to tmooc var a1 = document.getElementById("a1"); //想获得a1的href属性值 console.log(a1.href); //修改a1的title属性值 a1.title = "Welcome tmooc"; //判断a1是否包含target属性 console.log(a1.target !== ""); //移除a1的id属性 a1.id = ""; console.log(a1); console.dir(a1);
运行结果:

iv. 问题: HTML中有class属性来定义元素的样式类,而巧了,js中也有class关键字定义一种类型。两个class冲突了!
解决: DOM妥协了!从此修改元素的class属性,都必须更名为className。反之,修改className,就等效于修改元素的class属性。
v. 示例: 下拉菜单 手风琴效果

1_menu.html
1. 实现伸缩二级菜单 li { list-style: none; } li span { padding-left: 20px; cursor: pointer; background: url("images/add.png") no-repeat center left; } li ul { display: none; } .open { background: url("images/minus.png") no-repeat center left; } .open + ul { display: block; } - 考勤管理
- 日常考勤
- 请假申请
- 加班/出差
- 信息中心
- 通知公告
- 公司新闻
- 规章制度
- 协同办公
- 公文流转
- 文件中心
- 内部邮件
- 即时通信
- 短信提醒
//DOM 4步 //1. 查找触发事件的元素 //本例中: 查找所有li下的span var spans = document.querySelectorAll("li>span"); //2. 绑定事件处理函数 //本例中: 遍历找到的每个span,为每个span绑定单击事件 for (var span of spans) { span.onclick = function () { //3. 查找要修改的元素 //4. 修改元素 //本例中: //如果当前span自己是开着的 //其实就是看当前span的class属性值是不是open // if(this.getAttribute("class")=="open"){ if (this.className == "open") { //只要把自己关上即可!不用管别的span //其实就是清除当前span的class属性值 // this.setAttribute("class","") this.className = ""; } else { //否则如果当前span不是开着的 //先遍历所有span,清除每个span的class for (var span of spans) {// span.setAttribute("class","");span.className = ""; } //再只给当前单击的span自己加class open // this.setAttribute("class","open"); this.className = "open"; } }; }
运行结果:

(2). bool类型的HTML标准属性
a. 什么是bool类型的HTML标准属性: 在HTML标准属性中,有一类属性只要放在元素上,即使不提供=属性值,也能发挥作用!
b. 比如: <input type="button" disabled>
<input type="radio" checked>
c. 问题: 因为这种属性没有=属性值,所以不能用旧的核心DOM4个函数来操作。
d. 解决: 今后只要访问bool类型的HTML标准属性,都只能用HTML DOM打.访问。比如: 元素.disabled 元素.checked。且属性值必须是bool类型的true或false。
e. 补: css中其实已经提供了一套伪类选择器,专门选择处于某种状态的元素!——状态伪类,包括:
1) :checked —— 专门选择被选中的元素
2) :disabled —— 专门选择被禁用的元素
... ...
f. 示例: 全选 取消全选
2_selectAll.html
全选和取消全选 管理员列表
全选 管理员ID 姓名 操作 1 Tester 修改 删除 2 Manager 修改 删除 3 Analyst 修改 删除 4 Admin 修改 删除
/*点上方的全选,控制下方的所有checkbox*/ //DOM 4步 //1. 查找触发事件的元素 //本例中: 查找表头中的input var inputAll = document.querySelector( "table>thead input" //复习第二阶段选择器 ); //2. 绑定事件处理函数 inputAll.onclick = function () { //3. 查找要修改的元素 //本例中: 查找tbody下的所有input var inputs = document.querySelectorAll("table>tbody input"); //4. 修改元素 //本例中: 让下边每个input的checked状态和当前点击的全选checkbox的checked状态一致 for (var input of inputs) { input.checked = this.checked; } }; /*点下方的每个,都有可能影响上方的全选*/ //DOM 4步 //1. 查找触发事件的元素 //本例中: 查找tbody下所有input var inputs = document.querySelectorAll("table>tbody input"); //2. 绑定事件处理函数 //本例中: 遍历找到的每个input元素 for (var input of inputs) { //每遍历一个input,就绑定单击事件 input.onclick = function () { //3. 查找要修改的元素 //本例中: 无论点下方哪个input,都只可能影响thead中的一个input var inputAll = document.querySelector("table>thead input"); //4. 修改元素 //尝试查找tbody下未选中的一个input var unchecked = document.querySelector("tbody input:not(:checked)"); //复习第二阶段选择器 //如果找到未选中的 if (unchecked != null) { //上方的全选就不选中! inputAll.checked = false; } else { //否则如果没找到未选中的 //上方的全选就选中! inputAll.checked = true; } }; }
运行结果:



(3). 自定义扩展属性
a. 什么是自定义扩展属性: HTML标准中没有规定的,程序员根据自己的需要,自发的添加到元素上的自定义属性。
b. 何时会使用到自定义扩展属性: 2种情况:
1). 自定义扩展属性经常代替id, class, 元素等其他选择器,作为查找触发事件的元素的条件。
i. id选择器的问题: 一次只能找一个元素
ii. 元素选择器的问题: 实现同一种页面效果,完全可能使用不同的元素
比如,想要在页面上实现一种按钮,我们可以有多种元素作为备选,如button、input,想要做的好看一点div、span、a标签等元素都可以,所以我们发现可选的元素选择器不是唯一的,因此,实现同一种页面效果,完全可能使用不同的元素。
这就会影响js的操作,比如使用DOM查找元素,你一开始是按照button标签来查找元素的,后来有人发现使用button做的按钮太难看了,直接换成了a或span标签做按钮,然后按照a或span标签写了很好看的css的样式,但是对方在用a或span替换button做按钮时,如果不知道你写的js是以button元素作为查询条件来写的,这就会导致你的js不能正常执行,如此说来,元素选择器太容易发生变化了,此时,可以使用自定义扩展属性就是一个好的选择。
iii. class选择器的问题: class属性本职工作是为元素添加样式!因为样式经常发生变化,所以class属性也经常变化!
2). 在客户端元素上临时缓存业务所需的数据
c. 如何使用自定义扩展属性: HTML5标准
1). 手工在HTML元素上添加自定义属性:
<元素 data-属性名="属性值"> 注意:属性值可以没有,大部分情况下都会有值
2). js程序中访问自定义扩展属性:
i. 问题: 因为自定义扩展属性不是HTML标准规定的标准属性,所以HTML DOM并没有把自定义扩展属性提前保存到内存中的元素对象上!就无法用.方式快速访问!
ii. 解决: 2种:
① 用回旧核心DOM函数:
元素.getAttribute("data-自定义属性名")
元素.setAttribute("data-自定义属性名","新属性值")
②HTML5标准中提供了简写: HTML5标准用dataset属性将所有data-开头的自定义属性集中保存起来!访问时,可以用"元素.dataset.自定义属性名"访问自定义扩展属性
d. 示例: 使用自定义属性记录按钮的点击次数:
3_data-.html
Document //DOM 4步 //1. 查找触发事件的元素 //本例中: 查找带有data-n属性的元素 //复习第二阶段属性选择器 var btn = document.querySelector("[data-n]"); //2. 绑定事件处理函数 btn.onclick = function () { //3. 查找要修改的元素 //本例中: 不用找,因为就是要修改自己 //4. 修改元素 //4.1 取出当前按钮身上自定义属性data-n的值 var n = parseInt( //this.getAttribute("data-n") this.dataset.n //页面上的一切都是字符串 ); //4.2 数量+1 n++; //4.3 将新值放回自定义属性中 //this.setAttribute("data-n",n); this.dataset.n = n; };
运行结果:

🌱 小常识: 前端中:
1. Attribute: 特指写在HTML代码中元素的开始标签中的HTML属性,比如:
2. Property: 特指js程序中对象中保存的可用.访问的属性,比如:
lilei.sname lilei.sage
⬛总结: DOM 5件事: 增删改查+事件绑定:
1. 查找元素: 4种查找方式
2. 修改元素: 3种东西可修改
(1). 修改内容: 3种内容可修改:
a. 获取或修改元素的HTML内容:
1). 元素.innerHTML
2). 获取时: 返回原始HTML内容
3). 修改时: 先将新内容交给浏览器编译,再显示给人看
b. 获取或修改元素的纯文本内容:
1). 元素.textContent
2). 获取时: 返回去掉内嵌标签,将特殊符号翻译为正文后的纯文本
3). 修改时: 不会将新内容交给浏览器编译,而是原样显示给人看
c. 获取或修改表单元素的值:
表单元素.value
(2). 修改属性: 3种
a. 字符串类型的HTML标准属性: 2种:
1). 旧核心DOM: 4个函数
i. 元素.getAttribute("属性名");
ii. 元素.setAttribute("属性名", "属性值")
iii. var bool=元素.hasAttribute("属性名")
iv. 元素.removeAttribute("属性名")
优点: 万能, 缺点: 繁琐
2). 新HTML DOM:
i. 元素.属性名
ii. 元素.属性名="属性值"
iii. 元素.属性名!==""
iv. 元素.属性名=""
优点: 简单, 缺点: 不万能
b. bool类型的HTML标准属性:
1). 不能用旧核心DOM4个函数修改
2). 只能用HTML DOM的"元素.属性名"方式获取或修改,且值为bool类型
c. 自定义扩展属性:
1) HTML中: <元素 data-自定义属性名="属性值">
2). js中: 2种: (不能用.访问)
i. 核心DOM:
var 属性值=元素.getAttribute("data-自定义属性名")
元素.setAttribute("data-自定义属性名","属性值")
ii. HTML5标准: 元素.dataset.自定义属性名