JS深挖(事件机制答疑——注册事件监听、事件响应操作、冒泡和捕获)

目录: 1、事件机制概念 2、注册事件监听的方法 3、事件操作 4、冒泡和捕获

1、事件机制
问题描述:
1)事件机制是如何起作用的?它跟事件循环机制有何区别?
答:
事件机制区分于事件循环,它是用户交互层面的,依靠的是事件流。
Dom事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。事件捕获最先发生,为提前拦截事件提供了可能。然后,实际的目标元素接收到事件。最后一个阶段是冒泡,最迟要在这个阶段响应事件。
所以是浏览器时刻监听用户操作,一旦触发了事件,就会触发对应的事件流,这时候如果注册了事件监听函数,就会被触发。如果有多个事件同时触发,就会依次执行事件响应。
用户通过对固定元素注册事件监听的方法,来手动添加事件响应函数。
2、事件监听的方法
问题描述:
1)几种方法?有何区别?
2) addEventListner的第三个参数?
1)有三种事件监听方法
HTML事件处理方法:特定元素支持的每个事件都可以使用事件处理程序的名字以 HTML 属性的形式来指定。此时属性的值必须是能够执行的 JavaScript 代码,正常会绑定为事件处理函数。这种方法最大的缺陷就是将HTML代码和JS代码混用,且当需要事件处理的元素非常多时,不适用。

【JS深挖(事件机制答疑——注册事件监听、事件响应操作、冒泡和捕获)】Dom0事件处理方法:把一个函数赋值给一个事件处理程序属性,它的最大局限是,一个事件只能绑定一个事件处理,若绑定多个,那么后面的会覆盖前面的。
let btn = document.getElementById("myBtn"); btn.onclick = function() { console.log(this.id); // "myBtn" };

Dom2事件处理程序:定义了两个方法:addEventListener()和 removeEventListener()。这两个方法暴露在所有 DOM 节点上,它们接收 3 个参数:事件名、事件处理函数和一个布尔值,true 表示在捕获阶段调用事件处理程序,false(默认值)表示在冒泡阶段调用事件处理程序。
与方法2不同,addEventListener 可以给一个事件注册多个listener。
let btn = document.getElementById("myBtn"); btn.addEventListener("click", () => { console.log(this.id); }, false);

需要注意的是,removeEventListener的几个参数,必须与addEventListener的保存完全一致,才能够取消监听。
let btn = document.getElementById("myBtn"); let handler = function() { console.log(this.id); }; btn.addEventListener("click", handler, false); // 取消 btn.removeEventListener("click", handler, false); // 有效果!

2)addEventListener的第三个参数
在旧版本的DOM规定中,第三个参数默认规定为设置当前事件监听是在冒泡(默认)/捕获阶段执行,它是一个boolean值,默认为false。但是实际目前第三个参数已经有更复杂的配置,它设置为一个叫option的对象,可用选项如下:
JS深挖(事件机制答疑——注册事件监听、事件响应操作、冒泡和捕获)
文章图片

3、事件操作
问题描述
1)事件处理的event对象是什么?能获取哪些信息?
答:
无论是哪种监听方法,event是传给事件处理程序的唯一变量,称为事件对象。事件对象包含与特定事件有关的属性和方法,其内容视情况不同。但是event事件对象固定包含一些公共属性和方法。
JS深挖(事件机制答疑——注册事件监听、事件响应操作、冒泡和捕获)
文章图片

JS深挖(事件机制答疑——注册事件监听、事件响应操作、冒泡和捕获)
文章图片

4、冒泡和捕获
问题描述:
1)如果祖先元素的事件处理已经被捕获,那么子孙还会触发事件监听嘛?
2)捕获和冒泡各自解除默认行为的方法?
1)答案是肯定的
由于事件流三个阶段是固定的,也就是无论是否绑定事件监听和处理,事件都会在事件流的三个阶段经过所有涉及到的元素,阻止的方法只有手动的添加阻止默认行为。
2)阻止默认行为的方法
使用event.stopPropagation()可以阻止冒泡和捕获阶段的默认行为,让后续的元素不受影响。

另外补充一下,想要阻止元素本身的默认事件响应行为,得用event.preventDefault(),如标签的跳转行为等。
let a = document.getElementById('alink'); a.addEventListener('click', (e) => { e.preventDefault(); })

    推荐阅读