【前端入门笔记14】事件模型笔记

213 阅读3分钟

监听函数

浏览器的事件模型,通过监听函数(listener)对事件做出反应。事件发生后,浏览器监听到了这个事件,就会执行对应的监听函数。

监听方法

window.addEventListener('load', doSomething, false);

EventTarget.addEventListener()用于在当前节点或对象上,定义一个特定事件的监听函数。一旦这个事件发生,就会执行监听函数。该方法没有返回值。

该方法接受三个参数:

  • type:事件名称,大小写敏感。
  • listener:监听函数。事件发生时,会调用该监听函数。
  • useCapture:布尔值,表示监听函数是否在捕获阶段(capture)触发(参见后文《事件的传播》部分),默认为false(监听函数只在冒泡阶段被触发)。该参数可选。

例子👇

function hello() {
  console.log('Hello world');
}

var button = document.getElementById('btn');
button.addEventListener('click', hello, false);

事件的传播

一个事件发生后,会在子元素和父元素之间传播(propagation),这种传播会分成三个阶段:

  • 第一阶段:从window对象传导到目标节点(上层传到底层),称为“捕获阶段”(capture phase)。
  • 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
  • 第三阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。

这种三阶段的传播模型,使得同一个事件会在多个节点上触发。也就是当一个事件发生后,会先进行事件捕获,再进行事件冒泡,这两个部分都会执行,程序员选择把事件加在捕获阶段还是冒泡阶段

事件传播的模型👇

捕获不可以取消,冒泡可以取消

e.stopPropagetion() 可以中断冒泡。

有的事件不支持取消冒泡,比如scroll event,具体是否可以取消可以查引文版MDN

事件代理

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)。

意义:

  1. 省内存。当需要监听多个元素的事件时,只需要给希望监听的父元素上加一个事件即可。
  2. 可以监听动态元素。浏览器只看点击的时候是否有这个元素,不管这个元素是多早出现的。

例子👇

var ul = document.querySelector('ul');

ul.addEventListener('click', function (event) {
  if (event.target.tagName.toLowerCase() === 'li') {
    // some code
  }
});

上面代码中,click事件的监听函数定义在ul节点,但是实际上,它处理的是子节点li的click事件。这样做的好处是,只要定义一个监听函数,就能处理多个子节点的事件,而不用在每个li节点上定义监听函数。而且以后再添加子节点,监听函数依然有效。