如何确保事件监听器只触发一次
有时候,我们只需要监听事件一次。假设,我们有一个链接到云端的文件,但该文件没有与我们共享。在这种情况下,绑定到按钮的事件监听器应该只触发一次,以便给予我们查看文件的权限,因为一旦请求被处理,就没有必要再次处理该请求。
有两种方式可以实现:
- 使用
once属性 - 在事件第一次触发后删除事件监听器
使用once属性
我们可以将一个对象作为参数传递给addEventListener方法,并指定事件仅被处理一次。这可以通过将属性once传递给对象来实现。如果我们将once设置为true,则事件只会被触发一次。
let btn = document.getElementById('btn');
btn.addEventListener("click", function() {
// onClick code
}, {once : true});
在事件第一次触发后删除事件监听器
我们将为具有处理函数的元素绑定一个事件监听器,并在处理函数内部删除为该元素添加的事件。
let btn = document.getElementById('btn');
function onClick(event){
btn.removeEventListener('click', onClick);
console.log("Event fired once, no more click will be handled");
}
btn.addEventListener('click', onClick);
以下代码展示如何创建一个通用函数来处理所有事件和元素。
function oneTimeListener(node, type, callback) {
// create event
node.addEventListener(type, function listener(e) {
// remove event listener
e.target.removeEventListener(e.type, listener);
// call handler with original context
return callback.call(this, e);
});
}
let btn = document.getElementById('btn');
function onClick(event){
console.log(event, this);
}
oneTimeListener(btn, 'click', onClick);
在上述代码中,我们向DOM元素添加了事件监听器。一旦事件第一次触发,我们就会删除绑定到它的事件监听器。这样,就像事件只被处理了一次一样。
扩展
Vue
Vue为v-on提供了事件修饰符once来指定事件最多触发一次
<button v-on:click.once="doThis"></button>
React
React中可以用ref来实现,其实还是用的addEventListener。
import React, { useEffect, useRef } from 'react'
const App = () => {
const ref = useRef()
// 等待DOM加载
useEffect(() => ref.addEventListener('click', () => alert('Hi'), { once: true })
return <button ref={ref}>Click on me (once)</button>
}
来源:How to ensure an event listener is only fired once in JavaScript
浙公网安备 33010602011771号