浏览器事件:为什么会有捕获过程和冒泡过程?

事件概述

事件来源于输入设备。常见的输入设备,鼠标键盘触摸屏。
鼠标和触摸屏有一定的共性,都被称为pointer设备,是指它的输入最终会被转换为屏幕上的一个pointer,不同点是精确度和支持的点的数量不一样。
我们点击鼠标或是触摸屏,是操作系统或是浏览器把这个信息对应到了一个逻辑按钮上,再使得与他的视图对点击有反应。

捕获和冒泡

刚刚提到,实际上点击事件来自触摸屏和鼠标,鼠标点击并没有位置信息,但是操作系统一般会根据位移的信息累积计算出来,提供给浏览器一个坐标。
那么,把这个坐标转化为具体的元素上事件的过程,就是捕获过程了。而冒泡过程,是符合人类理解逻辑的,当你按了电视机的开关,同时也按了电视。
所以可以理解为,捕获是计算机处理事件的逻辑;而冒泡是人类处理事件的逻辑。
在一个事件发生时,捕获和冒泡总是先后发生,跟你是是否监听无关联。
在实际监听事件时,建议这么使用捕获和冒泡:默认使用冒泡模式,当开发组件时,遇到需要父元素控制子元素的行为,可以使用捕获。
addEventListener 有三个参数:

  • 事件名称;
  • 事件处理函数;
  • 捕获还是冒泡。

事件处理函数不一定是函数,也可以是个JavaScript具有handleEvent方法的对象,如下示例:

var o = {
handleEvent: event => console.log(event)
}
document.body.addEventListener("keydown", o, false);

第三个参数不一定是bool值,也可以是个对象,它提供了更多选项。

  • once:只执行一次。
  • passive:承诺此事件监听不会调用preventDefault,这有助于性能。
  • useCapture:是否捕获(否则冒泡)。

实际开发中,不建议传第三个参数,因为冒泡是符合人类心智模型的。除非是组件或是库的使用者,那就总是需要关心捕获和冒泡了。

焦点

键盘事件是由坐标控制的,一般来说,操作系统都会提供一套焦点系统,但是浏览器一般选择在自己的系统里覆盖原本的焦点系统。
焦点系统也是视障用户访问的重要入口,所以设计合理的焦点系统对可访问性是非常重要的。
在旧时代,有一个经典的问题就是如何去掉输入框上的虚线,这个虚线就是Windows焦点系统附带的表现。不过现在Windows已经不用虚线框表示了。
焦点系统认为整个UI系统中,有且仅有一个“聚焦”的元素,所有的键盘事件的目标元素都是这个聚焦元素。
Tab键可以用来切换到下一个可聚焦元素,焦点系统占用了Tab键,但是可以使用JavaScript阻止这一行为。
浏览器还提供了API来操作焦点。如:

document.body.focus()
document.body.blur()

其实原本焦点系统不需要捕获过程,为了跟pointer设备保持一致,也规定了从外向内传播的捕获过程。

自定义事件

此文章为8月Day1学习笔记,内容来源于极客时间《重学前端》,日拱一卒,每天进步一点点💪💪

豪猪
4 声望4 粉丝

undefined