当我单击按钮时,我会看到控制台消息,显示我已单击它们。当我取消选中该复选框然后单击按钮时,我预计不会出现控制台消息,但我仍然看到它们。为什么不removeEventListener
删除事件监听器?
const buttons = document.querySelectorAll('ul li button');
function initialize() {
for (let i = 0; i < buttons.length; i++) {
function doSomething() {
console.log(`You clicked on ${buttons[i].textContent}`);
}
if (document.querySelector('#mode').checked) {
buttons[i].addEventListener('click', doSomething);
} else {
buttons[i].removeEventListener('click', doSomething);
}
}
}
document.querySelector('#mode').addEventListener('click', initialize);
initialize();
<input id='mode' type='checkbox' checked/>
<label for='mode'>Do something when you click</label>
<ul>
<li><button>One</button>
<li><button>Two</button>
<li><button>Three</button>
<li><button>Four</button>
我无法定义doSomething
在 for 循环之外,因为我需要i
做其他事情(为了简单起见,此处未显示)。我确实需要为每个索引使用不同的处理程序。
现在,doSomething
是在 for 循环内部定义的,这意味着每次initialize
执行后,你最终会得到一个名为的新函数doSomething
. So addEventListener
添加一个名为的函数doSomething
, and removeEventListener
尝试删除不同的函数(也称为doSomething
)。新的doSomething
从未注册为事件侦听器,因此无法将其删除,并且旧的doSomething
超出了范围,因此我们无法引用它来删除它。相反,您可以动态生成一次函数并在中引用它们initialize
.
const buttons = document.querySelectorAll('ul li button');
const buttonFunctions = [];
for (let i = 0; i < buttons.length; i++) {
buttonFunctions[i] = function doSomething() {
console.log(`You clicked on ${buttons[i].textContent}`);
}
}
function initialize() {
for (let i = 0; i < buttons.length; i++) {
if (document.querySelector('#mode').checked) {
buttons[i].addEventListener('click', buttonFunctions[i]);
} else {
buttons[i].removeEventListener('click', buttonFunctions[i]);
}
}
}
document.querySelector('#mode').addEventListener('click', initialize);
initialize();
<input id='mode' type='checkbox' checked/>
<label for='mode'>Do something when you click</label>
<ul>
<li><button>One</button>
<li><button>Two</button>
<li><button>Three</button>
<li><button>Four</button>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)