JavaScript之DOM 操作
- 一、DOM 获取
- 二、添加元素
- 三、修改元素
- 四、删除元素
- 五、Web Storage
- 六、定时任务和延时操作
一、DOM 获取
文档对象模型简称 DOM,DOM 是一种 HTML/XHTML 页面的编程接口(API)。 它提供了一种文档的结构化地图,还有一组方法, 以便与所含元素交互。实际上,它是把标记方式转换为 JavaScript 可以理解的格式。简单的说,DOM 就像页面上所有元素的一个地图。Web 前端开发者可以使用它通过名字和元素来找到元素,然后添加、修改或删除元素及其内容。
1.获取 HTML 元素
在 DOM 中有三种方法能够获取元素节点,分别是通过元素 ID、通过标签名称和通过类名称来进行获取。
①getElementById
DOM 提供了一个名为 getElementByld 的方法,这个方法将返回一个有着给定 id 属性值的元素节点对应的对象,其使用方法如下所示:
var elementById = document.getElementById(`test_id`);
这个调用将返回一个对象,这个对象对应着 document 对象里的一个独一无二的元素,即元素 id 属性值为 test_id 的节点对象。可以通过使用 typeof 操作符来验证这一点, typeof 操作符能够定义操作数是一个字符串、数值、函数、布尔值还是对象。 innerText 表示节点内部的文本内容。
console.info(typeof elementById)
console.info(elementById.innerText)
②getElementsByTagName
getElementsByTagName 方法返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。类似于 getElementByld,这个方法也是只有一个参数的函数,它的参数是标签的名字,其使用方法如下所示:
var elementsByTagName = document.getElementsByTagName(`div`);
它与 getElementById 方法有许多相似之处,但它返回的是一个数组,在编写脚本的时候要注意区分开来。这个数组里的每一个元素都是一个对象,可以使用 getElementsByTagName 方法结合循环语句与 typeof 操作符进行验证,其使用方法如下所示:
<body>
<div>张三</div>
<div>李四</div>
<div>王二</div>
<script>
var elementsByTagName = document.getElementsByTagName(`div`);
for (var i = 0; i < elementsByTagName.length; i++) {
console.info(elementsByTagName[i].innerText)
}
</script>
</body>
注意:即使在整个文档中这个标签只有一个元素,getElementsByTagName 方法返回的也是一个数组,只是这个数组的长度为 1。
getElementsByTagName 方法允许把一个通配符作为它的参数,而这意味着文档里的每个元素都将在这个函数所返回的数组里占有一席之地。通配符“*”必须放在引号里面,这是为了让通配符与乘法操作符有所区别。下面的代码可以得到文档中总共有多少个元素节点。
document.getElementsByTagName(`*`);
当然,还可以将 getElementsByTagName 与 getElementByld 结合起来使用,比如想要得到某个 id 属性值为 my_id 的元素包含多少个列表项,其实现代码如下所示:
<body>
<div id="my_id">
<div>张三</div>
<div>李四</div>
</div>
<div>王二</div>
<script>
var elementById = document.getElementById("my_id");
var elementsByTagName = elementById.getElementsByTagName("div");
for (var i = 0; i < elementsByTagName.length; i++) {
console.info(elementsByTagName[i].innerHTML)
}
</script>
</body>
③getElementsByClassName
HTML5 DOM 中新增了一个方法:getElementsByClassName。这个方法能够通过 class 属性中的类名来访问元素。不过由于这是一个新增方法,某些浏览器中可能还未支持此方法的解析,其在 Internet Explorer 5/6/7/8 中无效,因此在使用时要注意兼容性。getElementsByClassName 方法getElementsByTagName 方法相似,也只接受一个参数, 就是类名,其使用方法如下所示:
<body>
<div class="my_class">1</div>
<div class="my_class">2</div>
<div class="my_class">3</div>
<script>
var elementsByClassName = document.getElementsByClassName("my_class");
for (var i = 0; i < elementsByClassName.length; i++) {
alert(elementsByClassName[i].innerHTML)
}
</script>
</body>
返回值与 getElementsByTagName 方法的返回值类似,都是一个具有相同类名的元素的数组。
getElementsByClassName 方法还可查找那些带有多个类名的元素。如果要指定多个类名只需在字符串参数中用空格分隔开类名即可,使用方法如下所示:
<div class="my_class">1</div>
<div class="my_class1 my_class">2</div>
<div class="my_class">3</div>
<script>
var elementsByClassName = document.getElementsByClassName("my_class my_class1");
for (var i = 0; i < elementsByClassName.length; i++) {
alert(elementsByClassName[i].innerHTML)
}
</script>
注意:由于文档是从上往下在浏览器中加载,如果获取节点的代码写在节点之前,则无法正常获取该节点返回 null 对象。需要指定在页面加载完成后再获取节点。
<script>
window.onload = function () {//页面加载完成后执行
let dom = document.getElementById("my_id");
console.info(dom)
}
</script>
二、添加元素
如果需要向 HTML 中添加新元素,那么首先便需要创建该元素,然后向已存在的元素追加创建的新元素。
document.createElement() 方法用来创建新的 Element 节点和 Text 节点,而方法 node.appendChild() 可以用来将创建好的元素添加到一个文档,其具体实现方法如下。
<div id="my_div">
</div>
<script>
var element = document.createElement("p");
element.innerText ="这是段落";
document.getElementById("my_div").appendChild(element);
</script>
练习:大写字母排版:将 css 篇的 display 练习使用循环输出 A-Z 全部字符。
参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>盒子和边练习</title>
<style>
* {
padding: 0;
margin: 0;
}
#content {
margin: 10px auto;
border: 2px dotted #000000;
width: 600px;
display: table;
}
#content div {
background: #907e35;
display: inline-block;
width: 180px;
height: 180px;
margin: 10px;
text-align: center;
color: white;
line-height: 180px;
font-size: 100px;
}
</style>
</head>
<body>
<div id="content">
</div>
<script>
for (let i = 65; i < 91; i++) {
let element = document.createElement("div");
element.append(String.fromCharCode(i));
document.getElementById("content").appendChild(element);
}
</script>
</body>
</html>
三、修改元素
修改元素包含三个部分的内容:修改元素内容、修改元素属性和修改元素样式。
①修改元素的内容
修改元素内容的最简单方法便是使用 innerHTML 属性,使用该属性可以对元素的内容重新赋值,从而达到修改元素内容的效果,其使用方法如下所示:
document.getElementById("my_div").innerHTML = "<p>这是一个段落</p>";
②修改元素属性
在得到需要的元素以后,就可以设法获取它的各个属性,getAttribute() 方法就是专门用来获取元素属性的,相应的也可以使用 setAttribute() 方法来更改元素节点的属性值。
案例:
<div id="my_div" title="哈哈哈"></div>
<script>
alert(document.getElementById("my_div").getAttribute("title"));
</script>
setAttribute() 方法是用来设置属性的,它允许对属性节点的值做出修改,与getAtribute方法一样, 它也是只能用于元素节点,其使用方法如下所示:
object.setAttribute(attribute,value);
案例:
<div id="my_div" title="哈哈哈">
div
</div>
<script>
document.getElementById("my_div").setAttribute("title","嘻嘻嘻")
</script>
③修改元素的样式
<p id="p2">Hello World!</p>
<script>
document.getElementById("p2").style.color="blue";
</script>
练习:
1.使用三个按钮控制 HTML 文档的 body 的背景颜色。
参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>盒子和边练习</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
background-color: dodgerblue;
}
.btn-group {
position: fixed;
bottom: 0;
text-align: center;
width: 100%;
}
.btn-group button {
width: 150px;
height: 50px;
text-align: center;
line-height: 50px;
border: none;
font-size: 25px;
}
</style>
</head>
<body>
<div class="btn-group">
<button onclick="changeColor('dodgerblue')">dodgerblue</button>
<button onclick="changeColor('purple')">purple</button>
<button onclick="changeColor('gray')">gray</button>
</div>
<script>
function changeColor(str) {
document.body.style.backgroundColor = str;
}
</script>
</body>
</html>
四、删除元素
如果需要在 HTML 中删除元素,首先便需要获得该元素,然后得到该元素的父元素,最后通过 removeChild 方法删除该元素,其实现流程如下。
var child = document.getElementById("p1");
child.parentNode.removeChild(child);
案例:
<div>
<p>不被删除的节点</p>
<p id="p1">要被删除的节点</p>
</div>
<script>
var child = document.getElementById("p1");
child.parentNode.removeChild(child);
</script>
案例:动态删除
<div>
<input id="btn1" type="button" value="按钮1" onclick="deleteBtn('btn1')">
<input id="btn2" type="button" value="按钮2" onclick="deleteBtn('btn2')">
<input id="btn3" type="button" value="按钮3" onclick="deleteBtn('btn3')">
</div>
<script>
function deleteBtn(el) {
let elementById = document.getElementById(el);
elementById.parentNode.removeChild(elementById)
}
</script>
优化:
<div>
<input type="button" value="按钮1" onclick="deleteBtn(this)">
<input type="button" value="按钮2" onclick="deleteBtn(this)">
<input type="button" value="按钮3" onclick="deleteBtn(this)">
</div>
<script>
function deleteBtn(el) {
el.parentNode.removeChild(el)
}
</script>
练习:
1.表格指定删除:排版如下表格,并增加删除按钮,在点击删除按钮时能正常删除该条数据。
参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表格指定删除</title>
<style>
* {
padding: 0;
margin: 0;
}
table {
width: 600px;
margin: 20px auto;
border-collapse: collapse;
text-align: center;
}
table td, table th {
border: 1px solid #cad9ea;
color: #666;
height: 30px;
}
table thead th {
background-color: #CCE8EB;
width: 100px;
}
table tr:nth-child(odd) {
background: #fff;
}
table tr:nth-child(even) {
background: #F5FAFA;
}
</style>
</head>
<body>
<table border="1" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>工资</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tableData">
<tr>
<td>1</td>
<td>张三</td>
<td>3000</td>
<td>
<button onclick="deleteUser(this)">删除</button>
</td>
</tr>
<tr>
<td>2</td>
<td>李四</td>
<td>4000</td>
<td>
<button onclick="deleteUser(this)">删除</button>
</td>
</tr>
<tr>
<td>3</td>
<td>王二</td>
<td>3500</td>
<td>
<button onclick="deleteUser(this)">删除</button>
</td>
</tr>
<tr>
<td>4</td>
<td>麻子</td>
<td>3800</td>
<td>
<button onclick="deleteUser(this)">删除</button>
</td>
</tr>
</tbody>
</table>
<script>
function deleteUser(obj) {
//obj.parentNode.parentNode.remove();
let tr = obj.parentNode.parentNode;
let tab = document.getElementById("tableData")
tab.removeChild(tr);
}
</script>
</body>
</html>
五、Web Storage
Web Storage 是 HTML5 改良了 Cookie 存储机制后,新推出的本地存储机制,其作用是把网站中有用的信息存储到本地,然后根据实际需要从本地读取信息,主要分为 SessionStorage 和 LocalStorage 两种类型,其功能和用法基本上是相同的,只是保存数据的生存期限不同。SessionStorage 内容只存在浏览器关闭之前,浏览器一旦关闭则数据全部清空,而 localStorage 可以保存在浏览器关闭并重启后还存在。
Storage 对象在创建时会有一个相应的(key/value)键/值对列表可供访问,列表中的每一个键/值对称为数据项。Key 可以是任何字符串,Value 是简单的字符串。Storage 对象的属性和方法具体如下:
①length:返回当前 Storage 对象里保存的键/值对数量。
②key(index):该方法返回 Storage 中第 index 个键(key)的名称。键的顺序是由浏览器定义的,只要键的数量不改变,键的顺序也是不变的(添加或删除键会改变键的顺序,而仅仅改变已存在键对应的值不会改变键的顺序)。如果 index 大于等于键/值对的数量,则该方法返回值为空。
③getItem(key):该方法返回指定 key 对应的当前值。如果指定的 key 在当前 Storage 对象的键/值对列表中不存在,则该方法返回值为空。
④setItem(key,value):该方法首先检测指定的键/值对的键是否已存在于当前键值对列表。如果不存在,就把该键/值对添加到对象键/值对列表;如果存在,则进一步判断旧值与新值是否相等,如果不等,则用新值更新旧值,如果相等,则不做任何改变。
⑤removeItem(key):该方法从 Storage 对象键/值对列表中删除指定键对应的数据项。key 对应的数据项不存在时不做任何改变。
⑥clear():当前Storage对象键/值对列表中有数据项时,清空键/值对列表。对于空的键值对列表,不做任何改变。
localStorage.setItem("key",1);
var key = localStorage.getItem("key");
也可以简写为
localStorage.key=1;
var key = localStorage.key;
案例:
<div id="my_div">
<p>不被删除的节点</p>
<p id="p1">要被删除的节点</p>
<button onclick="deleteNode()">删除</button>
<button onclick="addNode()">添加</button>
</div>
<script>
if (localStorage.getItem("deleteP1")=="1"){
let child = document.getElementById("p1");
child.parentNode.removeChild(child);
}
function deleteNode() {
let child = document.getElementById("p1");
child.parentNode.removeChild(child);
localStorage.setItem("deleteP1","1")
}
function addNode() {
let child = document.getElementById("my_div");
let element = document.createElement("p");
element.append("要被删除的节点");
element.setAttribute("id","p1")
child.appendChild(element)
localStorage.setItem("deleteP1","0")
}
</script>
练习:如下计算器,在保证用户能正常输入情况下计算器能经得起刷新。
参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>章节练习</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: black;
color: white;
text-align: center;
}
h2 {
padding: 20px;
}
.content {
width: 400px;
margin: 10px auto;
border: white solid 1px;
}
.inputBox {
height: 50px;
font-size: 30px;
line-height: 50px;
text-align: right;
padding: 10px 10px;
}
.buttonGroup button {
width: 90px;
height: 90px;
background-color: white;
border: none;
float: left;
margin: 5px;
line-height: 90px;
font-size: 30px;
border-radius: 4px;
}
.cleanFloat {
clear: left;
padding: 10px;
}
</style>
</head>
<body>
<div class="content">
<h2>超级计算器</h2>
<hr>
<p class="inputBox" id="inputBox"></p>
<hr>
<div class="buttonGroup">
<button onclick="clearText()">C</button>
<button onclick="backspace()">←</button>
<button onclick="addChar('(')">(</button>
<button onclick="addChar(')')">)</button>
<button onclick="addChar(7)">7</button>
<button onclick="addChar(8)">8</button>
<button onclick="addChar(9)">9</button>
<button onclick="addChar('/')">/</button>
<button onclick="addChar(4)">4</button>
<button onclick="addChar(5)">5</button>
<button onclick="addChar(6)">6</button>
<button onclick="addChar('*')">*</button>
<button onclick="addChar(1)">1</button>
<button onclick="addChar(2)">2</button>
<button onclick="addChar(3)">3</button>
<button onclick="addChar('-')">-</button>
<button onclick="addChar(0)">0</button>
<button onclick="addChar('.')">.</button>
<button onclick="calculate()">=</button>
<button onclick="addChar('+')">+</button>
</div>
<div class="cleanFloat">
中国制造
</div>
</div>
<script>
if (localStorage.inputBox) {
document.getElementById("inputBox").innerText = localStorage.inputBox;
}
function addChar(c) {
document.getElementById("inputBox").innerText += c;
localStorage.inputBox = document.getElementById("inputBox").innerText;
}
function calculate() {
let str = document.getElementById("inputBox").innerText;
document.getElementById("inputBox").innerText = eval(str);
localStorage.inputBox = document.getElementById("inputBox").innerText;
}
function clearText() {
document.getElementById("inputBox").innerText = "";
localStorage.clear();
}
function backspace() {
let str = document.getElementById("inputBox").innerText;
document.getElementById("inputBox").innerText=str.substr(0, str.length-1);
localStorage.inputBox = document.getElementById("inputBox").innerText;
}
</script>
</body>
</html>
六、定时任务和延时操作
在实际开发中经常使用定时任务和延时操作,JavaScript 提供相应的 API 完成该操作。
定时任务:setInterval
var i = 0;
var id = setInterval(function () {
console.info(i);
i++;
if (i == 8) {
clearInterval(id);
}
}, 1000)
使用 setInterval(function,时间)完成定时任务的开启,该方法的返回值是一个任务 id 类型为一个数字。使用 clearInterval 清除定时任务。
延时操作:setTimeout
setTimeout(function () {
alert("三秒后弹出")
}, 3000)
使用 setTimeout(function,时间)完成延时操作。和 setInterval 一样时间的单位是毫秒,1000 毫秒=1秒。
练习:
1.变身小怪兽:创建一个 HTML 页面 上面有一张图片,“变大”,“变小”,“暂停” 三个按钮控制图片大小。当变大按钮被点击时,图片以每秒 30 px 的速度变大,其他按钮相同道理控制图片。
参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>章节练习</title>
<style>
.btn-group {
position: fixed;
bottom: 0;
text-align: center;
width: 100%;
}
.btn-group button {
width: 150px;
height: 50px;
background: #1e69e8;
text-align: center;
line-height: 50px;
border: none;
color: white;
font-size: 30px;
}
img {
margin: 0 auto;
display: block;
}
</style>
</head>
<body>
<img src="img/小怪兽.jpg" width="200">
<div class="btn-group">
<button onclick="big()">变大</button>
<button onclick="stop()">停止</button>
<button onclick="small()">变小</button>
</div>
<script>
var index = 0;
function big() {
if (index == 0) {
index = setInterval(function () {
document.getElementsByTagName("img")[0].width += 3;
}, 100)
}
}
function small() {
if (index == 0) {
index = setInterval(function () {
document.getElementsByTagName("img")[0].width -= 3;
}, 100)
}
}
function stop() {
clearInterval(index);
index = 0;
}
</script>
</body>
</html>
章节练习:
1.做一个时间实时显示的页面。
2.做一个基于内存的用户系统,在页面不刷新时,能完成用户的增删改查。
3.基于第二题,将对象持久化到浏览器缓存,使其在刷新时保持修改的数据不丢失。
参考代码:
第一题参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
background-color: black;
color: white;
font-size: 40px;
text-align: center;
}
p span {
border: 2px solid #333;
padding: 10px 4px;
}
</style>
</head>
<body>
<p id="time">
</p>
<script>
getTime();
function getTime() {
let date = new Date();
let hours = formatTime(date.getHours());
let minutes = formatTime(date.getMinutes());
let seconds = formatTime(date.getSeconds());
document.getElementById('time').innerHTML = hours + " : " + minutes + " : " + seconds;
setTimeout("getTime()", 500);
}
function formatTime(i) {
if (i < 10) {
i = "<span>0</span> <span>" + i + "</span>";
} else {
let j = i.toString().charAt(0);
let z = i.toString().charAt(1);
i = "<span>" + j + "</span> <span>" + z + "</span>";
}
return i;
}
</script>
</body>
</html>
第二、三题参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>章节练习</title>
<style>
* {
margin: 0;
padding: 0
}
table {
width: 600px;
margin: 20px auto;
border-collapse: collapse;
text-align: center;
}
table td, table th {
border: 1px solid #cad9ea;
color: #666;
height: 30px;
}
table thead th {
background-color: #CCE8EB;
width: 100px;
}
table tr:nth-child(odd) {
background: #fff;
}
table tr:nth-child(even) {
background: #F5FAFA;
}
input {
width: 70px;
}
button {
display: inline-block;
padding: 4px 8px;
margin: 0 6px;
text-shadow: 0 1px 1px rgba(0, 0, 0, .3);
color: #d9eef7;
border: solid 1px #0076a3;
background: #0095cd;
}
</style>
</head>
<body>
<table border="1" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>工资</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tableData">
</tbody>
</table>
<script>
var arr = [
{id: 1, name: "张三", sal: 3000},
{id: 2, name: "李四", sal: 4000},
{id: 3, name: "王二", sal: 3500},
{id: 4, name: "麻子", sal: 3800}];
// if (localStorage.userInfo) {
// arr = JSON.parse(localStorage.userInfo);
// }
function loadData() {
// localStorage.userInfo = JSON.stringify(arr);
var str = "";
arr.forEach((o, index) => {
str += `<tr><td>${o.id}</td><td>${o.name}</td><td>${o.sal}</td>
<td><button οnclick="updateUser(${index})">修改</button><button οnclick="deleteUser(${index})">删除</button></td></tr>`
})
str += `<tr><td><input id="userId"></td><td><input id="userName"></td><td><input id="userSal"></td>
<td><button οnclick="saveData()">保存</button><button οnclick="cancel()">取消</button></td></tr>`
document.getElementById("tableData").innerHTML = str;
}
loadData();
function deleteUser(index) {
arr.splice(index, 1);
loadData();
}
var updateIndex = -1;
function updateUser(index) {
updateIndex = index;
document.getElementById("userId").value = arr[index].id;
document.getElementById("userName").value = arr[index].name;
document.getElementById("userSal").value = arr[index].sal;
}
function saveData() {
var id = document.getElementById("userId").value;
var name = document.getElementById("userName").value;
var sal = document.getElementById("userSal").value;
if (updateIndex == -1) {
arr.push({id: id, name: name, sal: sal})
} else {
arr.forEach(o => {
if (o.id == id) {
o.name = name;
o.sal = sal;
}
})
}
loadData();
updateIndex = -1;
}
function cancel() {
document.getElementById("userId").value = "";
document.getElementById("userName").value = "";
document.getElementById("userSal").value = "";
updateIndex = -1;
}
</script>
</body>
</html>