跳到主要内容

事件委托与自定义事件

事件委托如何用一个处理程序管理一类事件?​

  • 原理: 利用事件冒泡, 在处理程序内读取 event.target 判断真实来源, 再用 switch/if 分派逻辑;
list.addEventListener("click", (event) => {
switch (event.target.id) {
case "doSomething":
document.title = "changed";
break;
case "goSomewhere":
location.href = "https://www.wrox.com";
break;
case "sayHi":
console.log("hi");
break;
}
});
  • 适合事件: click、mousedown、mouseup、keydown、keypress、keyup 等会冒泡的事件;
  • 优点: 减少注册数量从而降低内存占用, 且新增子元素无需重新绑定, 代码量更少;
  • 前提: 事件会冒泡, 且 target 能区分来源, 见 事件对象;

如何模拟事件?​

  • 步骤: 创建事件对象 → 初始化事件 → 用 dispatchEvent 派发;
const event = document.createEvent("MouseEvents");
event.initMouseEvent(
"click",
true,
true,
document.defaultView,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null,
);
btn.dispatchEvent(event);
  • 其他类型: "KeyboardEvent" 用 initKeyboardEvent 初始化, "HTMLEvents" 用 initEvent 初始化;

如何派发自定义事件?​

  • 事件类型: 用 CustomEvent 携带 detail 数据;
  • 派发: 在目标元素上调用 dispatchEvent, 事件按正常事件流传播, 可被祖先监听;
div.addEventListener("myevent", (event) => console.log("DIV: " + event.detail));
document.addEventListener("myevent", (event) => console.log("DOCUMENT: " + event.detail));

const event = document.createEvent("CustomEvent");
event.initCustomEvent("myevent", true, false, "Hello world!");
div.dispatchEvent(event);
// DIV: Hello world!
// DOCUMENT: Hello world!