Skip to content

如何在JavaScript中只监听一次事件?

事件监听器选项

EventTarget.addEventListener() 方法接受一个 options 对象参数,其中可以传递几个不同的标志,其中之一是 once。将 once 设置为 true 会导致事件处理程序在给定元素的每个事件中最多只执行一次

<button id="my-btn">点击我!</button>
const listenOnce = (el, evt, fn) =>
  el.addEventListener(evt, fn, { once: true });

listenOnce(
  document.getElementById('my-btn'),
  'click',
  () => console.log('你好!')
); // '你好!' 只会在第一次点击时被记录

请注意,一些旧的浏览器(如Internet Explorer)不支持此功能。如果您需要支持旧的浏览器,可以使用下面的基于标志的实现。

使用标志

如果您的目标是旧的浏览器,您可以使用一个基于标志的实现。这依赖于事件监听器改变 fired 标志的状态,从而导致对事件处理程序的后续调用被忽略。

const listenOnce = (el, evt, fn) => {
  let fired = false;
  el.addEventListener(evt, (e) => {
    if (!fired) fn(e);
    fired = true;
  });
};

```javascript
listenOnce(
  document.getElementById('my-btn'),
  'click',
  () => console.log('Hello!')
);  // 'Hello!' 只会在第一次点击时被记录

由于这个实现是针对旧版本浏览器的,所以请记住你可能需要将某些特性(如箭头函数)转译为确保兼容性

jQuery

在过去,jQuery非常流行,其中一个原因是它易于使用的事件处理API。我们通常会使用$.one()来创建一个事件处理程序,该处理程序在给定事件的每个元素上最多执行一次。

$('#my-btn').one('click', () => {
  console.log('Hello!');  // 'Hello!' 只会在第一次点击时被记录
});

然而,在现代时代,由于浏览器自身的API显著改进,jQuery似乎已经不再受欢迎。这个实现主要是为了完整性而包含的。