javascript - js:移除或禁用之前添加的某个事件的事件监听器
问题描述
以下面的例子(与codepen相同)
const div = document.querySelector('div');
function a(){
console.log('a');
}
function b(){
console.log('b');
}
div.addEventListener('click', e=>{
a();
});
div.addEventListener('click', e=>{
// I don't want all previous added event handlers to work, is there a way to remove it?
b();
});
div{
width: 200px;
height: 200px;
background: red;
}
<div></div>
预期的输出是b
;
在我的原始代码中,我有多个事件处理程序,例如click
,mousemove
等。有没有一种方法可以删除我之前添加的特定事件的所有事件侦听器?
例如,在开始时,click
我的按钮触发function A
;在中间,我考虑需要进行功能更改,所以function A
我想要function B
并且仅触发 ,而不是触发function B
。
我读过了:
但这并没有太大帮助。谢谢你的帮助。
更新
更具体地说,有没有办法阻止以前添加click
的新添加函数内部的事件侦听器,例如:
my_button.addEventListener('click', ()=>{
console.log('a');
});
my_button.addEventListener('click', ()=>{
// remove all previously added click handlers
console.log('b');
});
解决方案
感谢@Kayac,解决了这个问题:
// add a new method to element, oneEventListener,
// for a speficified event type, only save and execute last add handler
function elemental(el){
el.oneEventListener = (event, func) => {
if(el.lastEventListener == null){
el.lastEventListener = {};
}
if(el.lastEventListener[event] != null){
el.removeEventListener(event, el.lastEventListener[event]);
}
el.addEventListener(event, func);
el.lastEventListener[event] = func;
}
return el;
}
// eventhandler singleton, support querySelector, getElementById, etc, even support querySelectorAll and getElementsByClassName
function proxy(el) {
if(!(el instanceof NodeList)){
return elemental(el);
}else{
el.forEach(ele=>{
ele = elemental(ele);
});
return el;
}
}
const div = proxy(document.querySelector('div'));
// const div = document.querySelector('div');
div.oneEventListener('click', e=>{
console.log('a');
})
div.oneEventListener('click', e=>{
console.log('b');
})
div.oneEventListener('click', ()=>{
console.log('c');
})
div.oneEventListener('mouseover', ()=>{
console.log('aa');
})
div.oneEventListener('mouseover', ()=>{
console.log('bb');
})
div.oneEventListener('mouseover', ()=>{
console.log('cc');
})
div{
width: 200px;
height: 200px;
background: red;
}
<div></div>
更新
对于访问者,如果您正在寻找 html 选择器以允许您在事件侦听器上执行单例,则以下代码已针对性能进行了调整。
/* html element selector */
// element: one event maps to one handler
function elemental(el){
el.oneEventListener = (event, func) => {
if(el.lastEventListener == null){
el.lastEventListener = {};
}
if(el.lastEventListener[event] != null){
el.removeEventListener(event, el.lastEventListener[event]);
}
el.addEventListener(event, func);
el.lastEventListener[event] = func;
}
return el;
}
// querySelector -> element
function proxy(el){
return elemental(el);
}
// querySelectorAll -> NodeList
function proxyAll(el){
el.forEach(ele=>{
ele = elemental(ele);
});
return el;
}
/*
once proxy is implemented, by oneEventListener,
only one event listener of particular type will exist on that element,
if you call addEventListener, proxy doesn't interfer it.
which the eventlistener added will work normally.
*/
// proxy query selector
const pqs = function(str){
return proxy(document.querySelector(str));
}
// proxy query selector all
const pqsa = function(str){
return proxyAll(document.querySelectorAll(str));
}
解决方案
您需要通过引用删除以前的事件监听器: https ://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
试试这个:
const div = document.querySelector('div');
function a(){
console.log('a');
}
function b(){
console.log('b');
}
div.addEventListener('click', a);
// condition for changing event listener
if (true) {
div.removeEventListener('click', a);
}
div.addEventListener('click', b);
这应该只运行 b
推荐阅读
- python - 如何使用用户定义的消息从 python pandas 导出数据
- c++ - C ++以正确的方式在堆上声明一个静态连续多维数组
- swift - 如何创建图像数组,并在 Swift 中使用 draw() 将它们绘制出来?
- http - HTTP KeepAlive 可以作为 TCP KeepAlive 的替代品吗?
- python - 使用numpy数组时如何处理itertools.product?
- c# - 为什么在使用 VS Installer 时出现“无法加载文件或程序集”?
- android - 无法在 Playstore 中按应用名称找到应用
- vb.net - VB.NET:如何将所需数据从 Datagrid 视图 ComboBoxColumn 自动填充到另一个 ComboBoxColumn
- powershell - 使用 wgrib2 将 grib2 转换为 netcdf:批量问题
- r - R中滞后的单列移位值