自定义事件
JS中我们可以自定义事件并通过自己派发自己监听的方式使用自定义事件完成元素之间的联动。
通常父子级元素之间可以通过事件流中捕获冒泡过程进行联动,但同级元素之间想要事件联动,就可以使用自定义事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<div id="one">Hello One</div>
<div id="two">Hello Two</div>
<div id="three">Hello Three</div>
<script>
const one = document.getElementById("one");
const two = document.getElementById("two");
const three = document.getElementById("three");
// 自定义事件对象
const myEvent = new Event("myEvent");
// two和three元素监听自定义事件
two.addEventListener("myEvent", (event) => {
console.log(event.target);
});
three.addEventListener("myEvent", (event) => {
console.log(event.target);
});
// 点击one元素,two和three元素在内部派发自定义事件
one.addEventListener("click", () => {
two.dispatchEvent(myEvent);
three.dispatchEvent(myEvent);
});
</script>
</body>
</html>
派发事件使用dispatchEvent方法
事件代理
在父子级元素中,如果子元素很多且每个子元素都要监听相同的事件且事件处理函数的逻辑也相同,那么可以选择将监听过程放到父级元素,通过事件流中的捕获和冒泡进行触发,然后根据event.target获得目标触发元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<ul id="list">
<li>hello world 1</li>
<li>hello world 2</li>
<li>hello world 3</li>
</ul>
<script>
const ul = document.querySelector("#list");
// 在父级监听事件,通过捕获冒泡获得子元素事件,这就是事件代理。
ul.addEventListener("click", (event) => {
console.log(event.target);
});
</script>
</body>
</html>
上述代码中,我们想要监听li的点击事件,但是如果li元素很多那么为每一个li元素绑定事件会造成很大的开销,所以选择在ul上绑定事件,减少开销。
事件代理就是一种编程思路,本质上还是要理解事件流的三个阶段:捕获阶段,目标阶段,冒泡阶段。