前端 - JS - DOM操作和事件处理
一、DOM操作
节点:html文档中所有内容都是节点
节点树:DOM树
节点类型:1.元素,2.属性,3.文本,6.注释,9.文档,11.文档片断,其余为XML节点
节点集合类型:NodeList(节点列表)和HTMLCollection(HTML集合)
1. 获取节点(单个、多个、相邻节点、兄弟节点、子节点和属性节点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="" id="f1">
<input type="text" name="username" id="username">
</form>
<form action="" id="f2">
<input type="text" name="username" id="username">
</form>
<form action="" id="f3">
<input type="text" name="password" id="password">
</form>
<ul class="u">
<li class="uli">列表项1</li>
<li class="uli">列表项2</li>
<li class="uli">列表项3</li>
<li class="uli">列表项4</li>
</ul>
<ol class="o">
<li class="oli">列表项1</li>
<li class="oli">列表项2</li>
<li class="oli">列表项3</li>
<li class="oli">列表项4</li>
</ol>
<script>
//获取文档类型对象
console.log(document.doctype);
//获取html元素
console.log(document.documentElement);
//获取head元素
console.log(document.head);
//获取body元素
console.log(document.body);
//获取title元素
console.log(document.title);
//获取表单元素集合,节点集合类型为HTMLCollection
console.log(document.forms);
// 1. 根据标签获取,返回HTMLCollection对象
console.log(document.getElementsByTagName("ul"));
console.log(document.getElementsByTagName("form"));
// 2. 根据id获取
console.log(document.getElementById("f1"));
// 3. 根据类获取,返回HTMLCollection对象
console.log(document.getElementsByClassName("u"));
console.log(document.getElementsByClassName("oli"));
// 4. 根据name属性获取,返回NodeList对象
console.log(document.getElementsByName("password"));
console.log(document.getElementsByName("username"));
// 5. 根据CSS选择器获取,返回NodeList对象
console.log(document.querySelector(".uli"));
console.log(document.querySelectorAll(".uli"));
//1. 获取前一个相邻节点和获取前一个兄弟节点
console.log(document.getElementsByTagName("ol")[0].previousSibling);
console.log(document.getElementsByTagName("ol")[0].previousElementSibling);
//2. 获取下一个相邻节点和获取下一个兄弟节点
console.log(document.getElementsByTagName("ol")[0].nextSibling);
console.log(document.getElementsByTagName("ol")[0].nextElementSibling);
//3. 获取子节点,返回NodeList对象
console.log(document.getElementsByTagName("ol")[0].childNodes);
//4. 获取子节点,返回HTMLCollection对象
console.log(document.getElementsByTagName("ol")[0].children);
//5. 获取第一个子节点和获取第一个元素节点
console.log(document.getElementsByTagName("ol")[0].firstChild);
console.log(document.getElementsByTagName("ol")[0].firstElementChild);
//5. 获取最后一个子节点和获取最后一个元素节点
console.log(document.getElementsByTagName("ol")[0].lastChild);
console.log(document.getElementsByTagName("ol")[0].lastElementChild);
//获取某个元素的属性节点,返回NamedNodeMap对象
console.log(document.getElementById("f1").attributes);
</script>
</body>
</html>
2. 节点的增删改查
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<form action="" id="f1">
<input type="submit" value="提交" />
</form>
<form action="" id="f2">
<input type="text" name="username" id="username" />
</form>
<form action="" id="f3">
<input type="text" name="password" id="password" />
</form>
<button>重置</button>
<ul class="u">
<li class="uli">列表项1</li>
<li class="uli">列表项2</li>
<li class="uli">列表项3</li>
<li class="uli">列表项4</li>
</ul>
<ol class="o">
<li class="oli">列表项1</li>
<li class="oli">列表项2</li>
<li class="oli">列表项3</li>
<li class="oli">列表项4</li>
</ol>
<script>
//1. 返回节点类型、节点名称
console.log(document.getElementsByClassName("uli")[0].nodeType);
console.log(document.getElementsByClassName("uli")[0].nodeName);
//2. 返回节点的值
//文本节点的内容
console.log(
document.getElementsByTagName("button")[0].childNodes[0].nodeValue
);
//属性节点的值
console.log(
document.getElementsByTagName("input")[0].getAttributeNode("value")
.nodeValue
);
//value属性的值
console.log(document.getElementsByTagName("input")[0].value);
// 3. 创建节点
//创建元素节点
var li = document.createElement("li");
console.log(li);
//创建文本节点
var text = document.createTextNode("列表项5");
console.log(text);
//创建属性节点
var att = document.createAttribute("style");
att.nodeValue = "color:red";
console.log(att);
// 4. 增加子节点
//增加文本节点
li.appendChild(text);
console.log(li);
var ol = document.querySelector(".u");
//增加子节点
ol.appendChild(li);
//增加属性节点
ol.attributes.setNamedItem(att);
// 5. 插入子节点
var li1 = document.createElement("li");
var text1 = document.createTextNode("列表项6");
li1.appendChild(text1);
ol.insertBefore(li1, ol.childNodes[2]);
console.log(ol);
// 6. 删除节点
//删除子节点
ol.removeChild(ol.childNodes[1]);
//删除属性节点
ol.removeAttributeNode(att);
// 7. 修改节点的值
document.getElementsByTagName("input")[0].value = "修改";
// 8. 替换/更新节点
var li2 = document.createElement("li");
var text2 = document.createTextNode("列表项7");
li2.appendChild(text2);
ol.replaceChild(li2, ol.children[0]);
console.log(ol.children);
// 9. 查询是否含有子节点
console.log(ol.hasChildNodes());
//获取子元素
console.log(document.getElementsByTagName("ol")[0].children);
//获取属性节点的值
console.log(
document.getElementsByTagName("input")[0].getAttribute("value")
);
// 3. 创建节点
//创建元素节点
var li = document.createElement("li");
console.log(li);
</script>
</body>
</html>
3. NodeList和HTMLCollection的区别
相同点:都是类数组,都可以通过索引获取元素,索引从0开始,都有length属性
不同点:
1. 获取方法不同。前者通过querySelectorAll获取的文档节点,后者通过类名和标签获取的HTML元素
2. 获取节点元素方法不同。前者只能通过索引获取,后者还可通过name和id(namedItem()方法)获取
3. 前者包含所有的节点类型,后者只包含元素节点
4. DOMTokenList(元素类名列表)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<ul class="u">
<li class="uli">列表项1</li>
<li class="uli">列表项2</li>
<li class="uli">列表项3</li>
<li class="uli">列表项4</li>
</ul>
<ol class="o">
<li class="oli">列表项1</li>
<li class="oli">列表项2</li>
<li class="oli">列表项3</li>
<li class="oli">列表项4</li>
</ol>
</body>
<script>
//获取类名
console.log(document.getElementsByClassName("u")[0].className);
//获取classList对象
console.log(document.getElementsByClassName("u")[0].classList);
//增加类名
document.getElementsByClassName("u")[0].classList.add("u01");
//删除类名
document.getElementsByClassName("u")[0].classList.remove("u01");
//修改类名
document.getElementsByClassName("u")[0].classList.replace("u", "u01");
</script>
</html>
二、事件处理
1. 添加事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button onclick="alert('hello')">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<div class="d1">
<div class="d2">
<div class="d3"></div>
</div>
</div>
</body>
<script>
//添加事件方式1:给html元素绑定事件属性
//添加事件方式2:给html元素添加事件属性
var bth2 = document.querySelectorAll("button")[1];
bth2.onclick = function () {
alert(this.nodeName);
};
//添加事件方式3:监听html元素
var bth3 = document.querySelectorAll("button")[2];
bth3.addEventListener(
"click",
function () {
alert("world");
},
false
);
</script>
</html>
2. 事件派发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>按钮</button>
</body>
<script>
var bth = document.querySelector("button");
bth.addEventListener(
"click",
function () {
alert("hello");
},
false
);
//创建一个事件
var ev = new Event("click");
//向一个目标派发一个事件
bth.dispatchEvent(ev);
</script>
</html>
3. 事件传递(捕获)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="d1">
<div class="d2">
<div class="d3">
<button>按钮</button>
<div class="d4">
<div class="d5"></div>
</div>
</div>
</div>
</body>
<script>
var d1 = document.getElementsByClassName("d1")[0];
var d2 = document.getElementsByClassName("d2")[0];
var d3 = document.getElementsByClassName("d3")[0];
var d4 = document.getElementsByClassName("d4")[0];
var d5 = document.getElementsByClassName("d5")[0];
//事件捕获
d1.addEventListener(
"click",
function (ev) { console.log('d1') },
true
);
d2.addEventListener(
"click",
function (ev) { console.log('d2') },
true
);
d3.addEventListener(
"click",
function (ev) { console.log('d3') },
true
);
d4.addEventListener(
"click",
function (ev) { console.log('d4') },
true
);
d5.addEventListener(
"click",
function (ev) { console.log('d5') },
true
);
</script>
</html>
4. 事件传递(冒泡)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="d1">
<div class="d2">
<div class="d3">
<button>按钮</button>
<div class="d4">
<div class="d5"></div>
</div>
</div>
</div>
</body>
<script>
var d1 = document.getElementsByClassName("d1")[0];
var d2 = document.getElementsByClassName("d2")[0];
var d3 = document.getElementsByClassName("d3")[0];
var d4 = document.getElementsByClassName("d4")[0];
var d5 = document.getElementsByClassName("d5")[0];
//事件冒泡
d1.addEventListener(
"click",
function (ev) { console.log('d1') },
false
);
d2.addEventListener(
"click",
function (ev) { console.log('d2') },
false
);
d3.addEventListener(
"click",
function (ev) { console.log('d3') },
false
);
d4.addEventListener(
"click",
function (ev) { console.log('d4') },
false
);
d5.addEventListener(
"click",
function (ev) { console.log('d5') },
false
);
</script>
</html>
4. 事件委托
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
<script>
//子元素上的事件会冒泡到父元素上的同名事件上触发
document.querySelector("ul").addEventListener("click", function (ev) {
console.log(ev.target);
});
</script>
</html>
四、课程总结
- 今天学习了 JavaScript 的DOM操作和事件处理,通过上课认真听讲和认真完成老师布置的作业,使得我对 DOM和事件 的理解和运用更加深入和熟悉。最主要的知识点是明白和掌握了操作DOM和事件处理的特点以及基本用法。