前端问题清单——事件

85 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

事件来源于输入设备:比如键盘、鼠标、触摸屏。通过输入设备产生的事件令试图发生了变化,就是用户在页面上的交互。

事件的捕获和冒泡

事件的捕获和冒泡有点像茴字到底有几种写法。平常用的时候也不会很纠结到底是捕获还是冒泡,但是在前端的问题清单里,就争取能把这两个过程分清楚,弄明白。

以点击事件为例,鼠标点击是没有位置信息的,操作系统会根据点击的位置计算出一个坐标告诉浏览器,然后浏览器把这个坐标再放到具体的元素事件,这个过程就是事件的捕获。捕获是计算机处理事件的逻辑,而冒泡则是更符合人的理解,是人处理事件的逻辑。

捕获和冒泡发生的顺序:外部捕获,内部捕获,内部冒泡,外部冒泡。

需要注意的是:在触发一个事件时,捕获和冒泡是先后发生的,捕获发生在冒泡之前发生,与是否监听无关。

监听事件

addEventListener

有三种参数:

  • target.addEventListener(type, listener, options);

  • target.addEventListener(type, listener, useCapture);

  • target.addEventListener(type, listener, useCapture, wantsUntrusted ); //仅仅在火狐中支持

参数:

  • type:事件名称
  • listener:事件处理函数
  • options:指定listener属性的对象
    • 首先需要判断当前浏览器是否支持传options对象
    • 属性
      • capture:布尔值,指定listener在事件的捕获阶段是否是传播到eventTarget触发
      • once:布尔值,如果是true,表示listener在添加之后最多只被调用一次,调用之后就会自动移除
      • passive:布尔值,如果是true,表示listener永远不会调用preventDefault,如果仍然调用了preventDefault,客户端会忽略并且抛出警告
  • useCapture:布尔值,当值为true时,沿着DOM树向上冒泡的事件不会触发listener。默认值是false。比较古老的浏览器也是支持这种形式,因为在使用options的时候要先判断当前浏览器是否支持。

在日常的业务开发时,一般不会传第三个参数,也就是默认是useCapture:false

焦点事件

焦点通过输入设备,在整个UI系统中,有且仅有一个的有焦点的元素

焦点是和坐标相关的,现代浏览器都选择在自己的系统内覆盖操作系统的焦点系统

document.focus() //获取焦点

document.blur() //失去焦点

自定义事件

DOM API中的事件不能用于普通对象,所以提供了自定义事件

事件的声明

event = new Event(type, eventInit)

参数:

  • type:创建事件的名称
  • eventInit:可接受以下字段:
    • bubbles:布尔值,默认值为false,表示该事件是否冒泡
    • cancelable:布尔值,默认为false,表示该事件能否被取消
    • composed:布尔值,默认为false,表示事件是否能从shadow dom传递到普通的dom

通过自定义事件声明出的事件对象可以在任何元素触发

事件的触发

dispatchEvent:向指定的目标派发事件

  • 与浏览器的原生事件不同,原生事件是DOM派发的,通过eventloop异步调用事件处理,但是dispatchEvent是同步调用事件处理

总结

代码开发中关于事件用到的很多,可能偶尔会用的比较随便。自定义事件的出现,让事件有了更多的可能性,从而可以写出更多友好的交互行为。