事件处理(概述)

事件是在浏览器窗口内部触发的信号,用于通知浏览器或操作系统环境的变化。程序员可以创建事件处理程序代码,当事件触发时运行,从而使网页能够对变化做出适当的响应。

此页面提供了关于如何使用事件和事件处理程序的非常简短的“提示”。新的开发者应该阅读事件简介

有哪些可用的事件?

事件在发出事件的 JavaScript 对象的页面中或其下方有文档记录。例如,要了解在浏览器窗口或当前文档上触发的事件,请参阅WindowDocument中的事件部分。

你可以使用事件参考来了解哪些 JavaScript 对象为特定 API(例如动画、媒体等)触发事件。

注册事件处理程序

有两种推荐的注册处理程序的方法。可以通过将事件处理程序代码分配给目标元素对应的onevent属性,或者通过使用addEventListener()方法将处理程序注册为元素的侦听器,来使事件处理程序代码在事件触发时运行。在这两种情况下,处理程序都将接收一个符合Event接口(或派生接口)的对象。主要区别在于可以使用事件侦听器方法添加(或删除)多个事件处理程序。

警告:使用 HTML onevent 属性设置事件处理程序的第三种方法不推荐!它们会使标记膨胀,使其可读性降低,并且更难调试。有关更多信息,请参阅内联事件处理程序

使用 onevent 属性

按照惯例,触发事件的 JavaScript 对象具有相应的“onevent”属性(通过在事件名称前添加“on”来命名)。当事件触发时,调用这些属性来运行关联的处理程序代码,并且也可以由你自己的代码直接调用。

要设置事件处理程序代码,你可以将其分配给相应的 onevent 属性。每个元素的每个事件只能分配一个事件处理程序。如果需要,可以通过将另一个函数分配给同一属性来替换处理程序。

下面显示了如何使用onclick属性为click事件设置一个简单的greet()函数。

js
const btn = document.querySelector("button");

function greet(event) {
  console.log("greet:", event);
}

btn.onclick = greet;

请注意,表示事件的对象作为第一个参数传递给事件处理程序。此事件对象实现了或派生自Event接口。

EventTarget.addEventListener

在元素上设置事件处理程序最灵活的方法是使用EventTarget.addEventListener方法。这种方法允许将多个侦听器分配给一个元素,并在需要时删除侦听器(使用EventTarget.removeEventListener)。

注意:能够添加和删除事件处理程序使你可以例如在不同的情况下让同一个按钮执行不同的操作。此外,在更复杂的程序中,清理旧的/未使用的事件处理程序可以提高效率。

下面显示了如何将一个简单的greet()函数设置为click事件的侦听器/事件处理程序(如果需要,你可以使用 lambda 函数而不是命名函数)。再次注意,事件作为第一个参数传递给事件处理程序。

js
const btn = document.querySelector("button");

function greet(event) {
  console.log("greet:", event);
}

btn.addEventListener("click", greet);

该方法还可以接收其他参数/选项来控制捕获和删除事件的方式。有关更多信息,请参阅EventTarget.addEventListener参考页面。

使用中止信号

一个值得注意的事件侦听器功能是能够使用中止信号同时清理多个事件处理程序。

这是通过将相同的AbortSignal传递给要一起删除的所有事件处理程序的addEventListener()调用来完成的。然后,你可以对拥有AbortSignal的控制器调用abort(),它将删除使用该信号添加的所有事件处理程序。例如,要添加一个可以使用AbortSignal删除的事件处理程序

js
const controller = new AbortController();

btn.addEventListener(
  "click",
  (event) => {
    console.log("greet:", event);
  },
  { signal: controller.signal },
); // pass an AbortSignal to this handler

然后,可以使用以下方法删除上面代码创建的事件处理程序

js
controller.abort(); // removes any/all event handlers associated with this controller