批改状态:合格
老师批语:nodelist, 还有不少子集,如radiionodelist, 以后会遇到的
一、DOM操作
1-NodeList:
a-NodeList是一个节点的集合(既可以包含元素和其他节点),在DOM中,节点的类型总共有12种,通过判断节点的nodeType来判断节点的类型。
b-NodeList对象有个length属性和item()方法,length表示所获得的NodeList对象的节点个数,这里还是要强调的是节点,而item()可以传入一个索引来访问Nodelist中相应索引的元素。
c- js 节点有11种类型,但是与html相关的只有6个
| 类型名称 | 常数值 |
|---|---|
| 元素节点 | 1 |
| 属性节点 | 2 |
| 文本节点 | 3 |
| 实体名称节点 | 6 |
| 文档节点 | 9 |
| 文档片段节点 | 11 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>遍历元素节点</title>
</head>
<body>
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
</body>
<script>
var cl = console.log.bind(console);
var ul = document.querySelector("ul");
cl(ul);
// 子节点
cl(ul.childNodes);
cl(ul.childNodes.length);
cl(ul.childNodes[2]);
// js节点
cl(ul.childNodes[0]);
cl(ul.childNodes[0].nodeType);
cl(ul.childNodes[1].nodeValue);
cl(ul.childNodes[1].nodeName);
// 最后一个
cl(ul.childNodes[ul.childNodes.length - 1]);
cl(ul.childNodes[ul.childNodes.length - 2].nodeName);
// 遍历
var eles = [];
ul.childNodes.forEach(function (item) {
// 只返回类型为1的元素节点
if (item.nodeType === 1) this.push(item);
}, eles);
cl(eles);
//获取第一个子节点
cl(ul.firstChild);
// cl(ul.childNodes[0]);
cl(ul.childNodes[ul.childNodes.length - 1]);
// 最后一个子节点
cl(ul.lastChild);
// 前一个兄弟节点
cl(ul.lastChild.previousSibling);
// 后一个兄弟节点
cl(ul.firstChild.nextSibling);
</script>
</html>
2-HTMLCollection
a-HTMLCollection是元素集合,它和NodeList很像,有length属性来表示HTMLCollection对象的长度,也可以通过elements.item()传入元素索引来访问。
b-HTMLCollection的集合和NodeList对象一样也是动态的,他们获取的都是节点或元素集合的一个引用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>遍历元素节点</title>
</head>
<body>
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
</body>
<script>
var cl = console.log.bind(console);
var ul = document.querySelector("ul");
// children
// childNodes: 返回所有节点,包括元素,文本...
cl(ul.childNodes);
// children: 只返回元素
cl(ul.children);
cl(ul.children.length);
cl(ul.childElementCount);
// 第一个元素
cl(ul.firstElementChild);
// 最后一个
cl(ul.lastElementChild);
// 任何一个
cl(ul.children[2]);
// 前一个兄弟
cl(ul.children[2].previousElementSibling);
//后一个兄弟
cl(ul.children[3].nextElementSibling);
// HTMLCollection没有forEach
cl("-----------");
for (var i = 0; i < ul.childElementCount; i++) {
cl(ul.children.item(i));
}
</script>
</html>
3-NodeList和HTMLCollection的区别:
NodeList:文档节点集合
HTMLCollection: 文档元素集合
HTMLCollection相当于是NodeList中type=1的节点集合
二、事件
1-事件添加方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>事件添加方式</title>
</head>
<body>
<button onclick="var text=this.innerText;alert(text);">按钮1</button>
<button onclick="show(this)">按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
</body>
<script>
var cl = console.log.bind(console);
//1. 给html元素绑定事件属性
function show(ele) {
var text = ele.innerText;
alert(text);
}
// 2. 给html元素添加属性
var btn3 = document.querySelector("button:nth-of-type(3)");
btn3.onclick = function () {
alert(this.nodeName);
};
// 3. 监听器
var btn4 = document.querySelector("button:nth-of-type(4)");
// btn4.addEventListener(事件类型, 事件回调函数, 传递机制)
btn4.addEventListener(
"click",
function () {
alert(this.innerText);
},
// false: 冒泡阶段触发
false
);
// 4. 事件派发
var btn5 = document.querySelector("button:last-of-type");
btn5.addEventListener(
"click",
function () {
alert(this.innerText);
},
false
);
// 创建一个事件对象
var ev = new Event("click");
// 不用点击,也会自动的触发点击事件
btn5.dispatchEvent(ev);
</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>事件传递与事件委托/代理</title>
</head>
<body>
<div class="first">
<div class="second">
<div class="three">事件传递</div>
</div>
</div>
</body>
<script>
// 事件的捕获与冒泡
var cl = console.log.bind(console);
var first = document.querySelector(".first");
var second = document.querySelector(".second");
var three = document.querySelector(".three");
// true: 捕获阶段触发事件
first.addEventListener(
"click",
function (ev) {
// ev: 事件对象
// ev.type: 事件类型
// ev.target: 触发事件的元素
// ev.currentTarget: 绑定事件的元素
// cl(ev.target.classList.item(0));
cl(
"捕获阶段:" + "触发: " + ev.target.classList.item(0),
"绑定:" + ev.currentTarget.classList.item(0)
);
},
true
);
second.addEventListener(
"click",
function (ev) {
cl(
"捕获阶段:" + "触发: " + ev.target.classList.item(0),
"绑定:" + ev.currentTarget.classList.item(0)
);
},
true
);
three.addEventListener(
"click",
function (ev) {
cl(
"捕获阶段:" + "触发: " + ev.target.classList.item(0),
"绑定:" + ev.currentTarget.classList.item(0)
);
},
true
);
// false: 冒泡阶段触发事件
first.addEventListener(
"click",
function (ev) {
// ev: 事件对象
// ev.type: 事件类型
// ev.target: 触发事件的元素
// ev.currentTarget: 绑定事件的元素
// cl(ev.target.classList.item(0));
cl(
"冒泡阶段:" + "触发: " + ev.target.classList.item(0),
"绑定:" + ev.currentTarget.classList.item(0)
);
},
false
);
second.addEventListener(
"click",
function (ev) {
cl(
"冒泡阶段:" + "触发: " + ev.target.classList.item(0),
"绑定:" + ev.currentTarget.classList.item(0)
);
},
false
);
three.addEventListener(
"click",
function (ev) {
cl(
"冒泡阶段:" + "触发: " + ev.target.classList.item(0),
"绑定:" + ev.currentTarget.classList.item(0)
);
},
false
);
</script>
<!-- 冒泡实现事件的委托/代理 -->
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
<script>
document.querySelectorAll("ul li").forEach(function (item) {
item.addEventListener("click", function (ev) {
cl(this === ev.target);
cl("当前触发事件的元素是:", this);
});
});
// 事件委托/代理: 子元素上的事件会冒泡到父元素上的同名事件上触发
// document.querySelector("ul").addEventListener("click", function (ev) {
// // cl(ev.target);
// // cl(ev.currentTarget);
// // cl(this === ev.currentTarget);
// cl("当前触发事件的元素是:", ev.target);
// });
</script>
</html>
三、事件捕获与冒泡的原理
事件捕获: 就是像捕鱼收网那样,从外向里面触发。
冒泡: 像水烧开了一样,从内向外面扩散触发。
四、总结:通过本节课的学习对捕获与冒泡的原理有了认识,知道了事件委托/代理的实现方式,DOM中的NodeList与HTMLCollectio区别。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号