目录
方法一:使用 tbody.insertAdjacentHTML(xxx , xxx )
概念
文档对象模型(DOM)是表示和操作HTML和XML文档内容的基础API。API不是特别复杂,但是需要理解大量的架构细节。首先,应该理解HTML或XML文档的嵌套元素在DOM树对象中的表示。HTML文档的树状结构包含表示HTML标签或元素(如<body>、<p>)和表示文本字符串的节点,它也可能包含表示HTML注释的节点。如:
图中的每个方框是文档的一个节点,它表示一个Node对象。我们将在后续几节中讨论Node的属性和方法,并且可以在第四部分查找这些属性和方法。注意,图15-1包含3种不同类型的节点。树形的根部是Document节点,它代表整个文档。代表HTML元素的节点是Element节点,代表文本的节点是Text节点。Document、Element和Text是Node的子类,在第四部分中它们有自己的条目。Document和Element是两个重要的DOM类,本章大部分内容将阐述它们的属性和方法。
要使用DOM来操作网页,浏览器为我们提供的document对象,它是一个全局变量可以直接使用,document代表的是整个的网页
document对象
document对象
- document对象表示的是整个网页
- document对象的原型链:
HTMLDocument -> Document -> Node -> EventTarget -> Object.prototype -> null
- 凡是在原型链上存在的对象的属性和方法都可以通过Document去调用
- 部分属性:
document.documentElement --> html根元素
document.head --> head元素
document.title --> title元素
document.body --> body元素
document.links --> 获取页面中所有的超链接 ...
元素节点
元素节点对象(element)
- 在网页中,每一个标签都是一个元素节点
如何操作元素节点对象?
1. 通过document对象来获取元素节点
2. 通过document对象来创建元素节点
通过document来获取已有的元素节点:
根据id获取一个元素节点对象:
document.getElementById()
根据元素的class属性值获取一组元素节点对象:
- 返回的是一个类数组对象
- 该方法返回的结果是一个实时更新的集合 当网页中新添加元素时,集合也会实时的刷新
document.getElementsByClassName()
根据标签名获取一组元素节点对象,返回的结果是可以实时更新的集合:
document.getElementsByTagName()
//获取页面中所有的元素:
document.getElementsByTagName("\*")
根据name属性获取一组元素节点对象,返回一个实时更新的集合,主要用于表单项:
document.getElementsByName()
根据选择器去页面中查询元素: - 会返回一个类数组(不会实时更新)
document.querySelectorAll()
根据选择器去页面中查询第一个符合条件的元素:
document.querySelector()
创建一个元素节点:
根据标签名创建一个元素节点对象:
document.createElement()
div元素的原型链
HTMLDivElement -> HTMLElement -> Element -> Node -> ...
通过元素节点对象获取其他节点的方法
element.childNodes 获取当前元素的子节点(会包含空白的子节点)
element.children 获取当前元素的子元素
element.firstElementChild 获取当前元素的第一个子元素
element.lastElementChild 获取当前元素的最后一个子元素
element.nextElementSibling 获取当前元素的下一个兄弟元素
element.previousElementSibling 获取当前元素的前一个兄弟元素
element.parentNode 获取当前元素的父节点
element.tagName 获取当前元素的标签名
文本节点
在DOM中,网页中所有的文本内容都是文本节点对象,可以通过元素来获取其中的文本节点对象,但是我们通常不会这么做。
通过元素去修改文本
修改文本的三个属性
element.textContent
获取或修改元素中的文本内容( 获取的是标签中的内容,不会考虑css样式)
element.innerText
获取或修改元素中的文本内容
- innerText获取内容时,会考虑css样式
- 通过innerText去读取CSS样式,会触发网页的重排(计算CSS样式)
- 当字符串中有标签时,会自动对标签进行转义
element.innerHTML
获取或修改元素中的html代码
- 可以直接向元素中添加html代码 - innerHTML插入内容时,有被xss注入的风险
属性节点
在DOM也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作
如何操作属性节点:
方式一:
读取
元素.属性名 eg:input.type
(注意,class属性需要使用className来读取)
读取一个布尔值时,会返回true或false
修改
元素.属性名 = 属性值
方式二:
读取
元素.getAttribute(属性名)
修改
元素.setAttribute(属性名, 属性值)
删除
元素.removeAttribute(属性名)
事件
事件(event)
- 事件就是用户和页面之间发生的交互行为
比如:点击按钮、鼠标移动、双击按钮、敲击键盘、松开按键...
- 可以通过为事件绑定响应函数(回调函数),来完成和用户之间的交互
- 绑定响应函数的方式:
1.可以直接在元素的属性中设置
2.可以通过为元素的指定属性设置回调函数的形式来绑定事件(一个事件只能绑定一个响应函数)
3.可以通过元素addEventListener()方法来绑定事件
文档加载
网页是自上向下加载的,如果将js代码编写到网页的上边,
js代码在执行时,网页还没有加载完毕,这时会出现无法获取到DOM对象的情况
window.onload 事件会在窗口中的内容加载完毕之后才触发
document的DOMContentLoaded事件会在当前文档加载完毕之后触发
如何解决这个问题:
1. 将script标签编写到body的最后(*****)
2. 将代码编写到window.onload的回调函数中
3. 将代码编写到document对象的DOMContentLoaded的回调函数中(执行时机更早)
4. 将代码编写到外部的js文件中,然后以defer的形式进行引入(执行时机更早,早于DOMContentLoaded)(*****)
应用:表单中员工的添加和删除
实例:
题目要求:
1.点击删除超链接后,删除当前的员工信息
2.点击按钮后,将用户的信息插入到表格中
方法一:使用 tbody.insertAdjacentHTML(xxx , xxx )
缺点是容易被xxs攻击
删除员工信息思路步骤:
1.文档加载
2.在获取所有删除按钮之前,要消除超链接的跳转功能,可以使用 javascript:;
3.获取所有的超链接,(实际开发中要注意页面中还有其他超链接,这时应使用 querySelectorAll并结合选择器来选择想要的超链接)
4.为删除按钮绑定单击响应函数
5.每个删除按钮都要具备删除功能,单击响应函数中的this指的是点击的超链接,我们可以再根据找到其祖先从而删除表格中的tr一栏
6.删除前给出提示信息,根据用户给出的条件来确定是否删除
6.1获取删除者姓名
6.2是否删除 弹出一个友好的提示
7.删除当前员工 删除当前超链接所在的tr
添加员工信息思路步骤:
1.获取按钮
2.为点击按钮绑定响应函数
2.1获取输入的用户信息
3.将获取的信息创建为dom对象
方法一:使用 tbody.insertAdjacentHTML(xxx , xxx ) 缺点是容易被xxs攻击
3.1 我们要找到对象的插入位置,所以要获取tbody
3.2插入
方法二:创建节点然后再添加进去
3.1创建元素
3.2创建td
3.3添加文本
3.4将三个td添加到tr中
4.为新添加的超链接单独绑定响应函数(由于上边的超链接是新添加的,所以它的上边并没有绑定单级响应函数,所以新添加的员工无法删除)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.outer {
width: 400px;
margin: 100px auto;
text-align: center;
}
table {
width: 400px;
border-collapse: collapse;
margin-bottom: 20px;
}
td,
th {
border: 1px black solid;
padding: 10px 0;
}
form div {
margin: 10px 0;
}
</style>
<script>
/*
点击删除超链接后,删除当前的员工信息
*/
/* 本练习中的超链接,我们是不希望发生跳转,但是跳转行为是超链接的默认行为
只要点击超链接就会触发页面的跳转,事件中可以通过取消默认行为来阻止超链接的跳转
使用return false来取消默认行为,局限:只在 xxx.xxx = function(){}这种形式绑定的事件中才适用
*/
function delEmpHandler() {
//5.每个删除按钮都要具备删除功能,单击响应函数中的this指的是点击的超链接,我们可以再根据找到其祖先从而删除表格中的tr一栏
const tr = this.parentNode.parentNode
//6.删除前给出提示信息,根据用户给出的条件来确定是否删除
//6.1获取删除者姓名
const empName = tr.firstElementChild.textContent
//6.2是否删除 弹出一个友好的提示
let flag = confirm("你确定要删除【" + empName + "】吗?")
if (flag) {
//7.删除当前员工 删除当前超链接所在的tr
tr.remove()
}
}
//1.文档加载
window.onload = document.addEventListener("DOMContentLoaded", function () {
//2.在获取所有删除按钮之前,要消除超链接的跳转功能,可以使用 javascript:;
//3.获取所有的超链接,实际开发中要注意页面中还有其他超链接,这时应使用 querySelectorAll并结合选择器来选择想要的超链接
const links = document.links
//4.为删除按钮绑定单击响应函数
for (let i = 0; i < links.length; i++) {
//为避免重复声明 将其作为函数单独声明,后续也可方便调用
links[i].onclick = delEmpHandler
}
/*
点击按钮后,将用户的信息插入到表格中
*/
//1.获取按钮
const button = document.getElementById("btn");
const tbody = document.querySelector("tbody")
//2.为点击按钮绑定响应函数
button.onclick = function () {
//2.1获取输入的用户信息
const name = document.getElementById("name").value;
const email = document.getElementById("email").value;
const salary = document.getElementById("salary").value;
// 3.将获取的信息创建为dom对象
//3.1 我们要找到对象的插入位置,所以要获取tbody
//3.2插入
tbody.insertAdjacentHTML("beforeend",
`
<tr>
<td>${name}</td>
<td>${email}</td>
<td>${salary}</td>
<td><a href="javascript:;">删除</a></td>
</tr>
`
)
// 由于上边的超链接是新添加的,所以它的上边并没有绑定单级响应函数,所以新添加的员工无法删除
// 解决方式:为新添加的超链接单独绑定响应函数
links[links.length-1].onclick = delEmpHandler
}
})
</script>
</head>
<body>
<div class="outer">
<table>
<tbody>
<tr>
<th>姓名</th>
<th>邮件</th>
<th>薪资</th>
<th>操作</th>
</tr>
<tr>
<td>孙悟空</td>
<td>swk@hgs.com</td>
<td>10000</td>
<td><a href="javascript:;">删除</a></td>
</tr>
<tr>
<td>猪八戒</td>
<td>zbj@glz.com</td>
<td>8000</td>
<td><a href="javascript:;">删除</a></td>
</tr>
<tr>
<td>沙和尚</td>
<td>shs@lsh.com</td>
<td>6000</td>
<td><a href="javascript:;">删除</a></td>
</tr>
</tbody>
</table>
<form action="#">
<div>
<label for="name">姓名</label>
<input type="text" id="name" />
</div>
<div>
<label for="email">邮件</label>
<input type="email" id="email" />
</div>
<div>
<label for="salary">薪资</label>
<input type="number" id="salary" />
</div>
<button id="btn" type="button">添加</button>
</form>
</div>
</body>
</html>
方法二:创建节点然后再添加进去(更好)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.outer {
width: 400px;
margin: 100px auto;
text-align: center;
}
table {
width: 400px;
border-collapse: collapse;
margin-bottom: 20px;
}
td,
th {
border: 1px black solid;
padding: 10px 0;
}
form div {
margin: 10px 0;
}
</style>
<script>
/*
点击删除超链接后,删除当前的员工信息
*/
/* 本练习中的超链接,我们是不希望发生跳转,但是跳转行为是超链接的默认行为
只要点击超链接就会触发页面的跳转,事件中可以通过取消默认行为来阻止超链接的跳转
使用return false来取消默认行为,局限:只在 xxx.xxx = function(){}这种形式绑定的事件中才适用
*/
function delEmpHandler() {
//5.每个删除按钮都要具备删除功能,单击响应函数中的this指的是点击的超链接,我们可以再根据找到其祖先从而删除表格中的tr一栏
const tr = this.parentNode.parentNode
//6.删除前给出提示信息,根据用户给出的条件来确定是否删除
//6.1获取删除者姓名
const empName = tr.firstElementChild.textContent
//6.2是否删除 弹出一个友好的提示
let flag = confirm("你确定要删除【" + empName + "】吗?")
if (flag) {
//7.删除当前员工 删除当前超链接所在的tr
tr.remove()
}
}
//1.文档加载
window.onload = document.addEventListener("DOMContentLoaded", function () {
//2.在获取所有删除按钮之前,要消除超链接的跳转功能,可以使用 javascript:;
//3.获取所有的超链接,实际开发中要注意页面中还有其他超链接,这时应使用 querySelectorAll并结合选择器来选择想要的超链接
const links = document.links
//4.为删除按钮绑定单击响应函数
for (let i = 0; i < links.length; i++) {
//为避免重复声明 将其作为函数单独声明,后续也可方便调用
links[i].onclick = delEmpHandler
}
/*
点击按钮后,将用户的信息插入到表格中
*/
//1.获取按钮
const button = document.getElementById("btn");
const tbody = document.querySelector("tbody")
//2.为点击按钮绑定响应函数
button.onclick = function () {
//2.1获取输入的用户信息
const name = document.getElementById("name").value;
const email = document.getElementById("email").value;
const salary = document.getElementById("salary").value;
//3.1创建元素
const tr = document.createElement("tr")
//3.2创建td
const nameTd = document.createElement("td");
const emailTd = document.createElement("td");
const salaryTd = document.createElement("td");
//3.3添加文本
nameTd.innerText = name
emailTd.textContent = email;
salaryTd.textContent =salary;
//3.4将三个td添加到tr中
tr.appendChild(nameTd)
tr.appendChild(emailTd)
tr.appendChild(salaryTd)
tr.insertAdjacentHTML("beforeend", '<td><a href="javascript:;">删除</a></td>')
tbody.appendChild(tr)
// 由于上边的超链接是新添加的,所以它的上边并没有绑定单级响应函数,所以新添加的员工无法删除
// 解决方式:为新添加的超链接单独绑定响应函数
links[links.length - 1].onclick = delEmpHandler
}
})
</script>
</head>
<body>
<div class="outer">
<table>
<tbody>
<tr>
<th>姓名</th>
<th>邮件</th>
<th>薪资</th>
<th>操作</th>
</tr>
<tr>
<td>孙悟空</td>
<td>swk@hgs.com</td>
<td>10000</td>
<td><a href="javascript:;">删除</a></td>
</tr>
<tr>
<td>猪八戒</td>
<td>zbj@glz.com</td>
<td>8000</td>
<td><a href="javascript:;">删除</a></td>
</tr>
<tr>
<td>沙和尚</td>
<td>shs@lsh.com</td>
<td>6000</td>
<td><a href="javascript:;">删除</a></td>
</tr>
</tbody>
</table>
<form action="#">
<div>
<label for="name">姓名</label>
<input type="text" id="name" />
</div>
<div>
<label for="email">邮件</label>
<input type="email" id="email" />
</div>
<div>
<label for="salary">薪资</label>
<input type="number" id="salary" />
</div>
<button id="btn" type="button">添加</button>
</form>
</div>
</body>
</html>