跳到主要内容

事件流与处理程序

事件流分为哪几个阶段?​

  • 顺序: 事件捕获 → 到达目标 → 事件冒泡;
  • 事件捕获: 从 document 向下传播到触发节点;
  • 到达目标: 事件流抵达触发节点, 由捕获转向冒泡;
  • 事件冒泡: 从最深的节点依次向上传播到外层节点;

有哪几种事件处理程序写法?​

  • HTML 事件处理程序: 属性内联, 作用域为全局, this 指向元素本身, 在冒泡阶段处理;
<input type="button" value="Click Me" onclick="console.log(this.value)" />
  • DOM0 事件处理程序: 直接给 onclick 等属性赋值, this 指向元素, 在冒泡阶段处理; 置为 null 即移除;
btn.onclick = function () {
console.log(this.id);
};
btn.onclick = null;
  • DOM2 事件处理程序: 用 addEventListener 注册, 可注册多个并按添加顺序触发;
const handler = function () {
console.log(this.id);
};
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false);

DOM2 注册有哪些可选配置?​

选项含义
capture是否在捕获阶段处理, 默认 false(冒泡阶段)
once是否只触发一次, 默认 false
  • 移除限制: removeEventListener 必须传入同一个函数引用与相同配置, 因此匿名函数无法移除;

为什么需要显式删除事件处理程序?​

  • 原因: 删除节点或卸载页面时, 绑定的事件处理程序不一定随节点一起被回收;
  • 做法: 在移除节点或页面卸载前手动调用 removeEventListener;
  • 关联: 事件引用会延长闭包与外层变量对象的生命周期, 见 闭包;