function show1() {
console.log("ok1");
document.getElementById("a2").removeEventListener("click", delegate);
}
function show2() {
console.log("ok2");
}
function show3() {
console.log("ok3");
}
function delegate(event) {
var flag = event.target;
switch (flag.id) {
case "a1":
show1();
break;
case "a2":
show2();
break;
case "a3":
show3();
break;
}
}
ob = document.getElementById("tl");
ob.addEventListener("click", delegate);
<ul id="tl">
<li id="a1">a1</li>
<li id="a2">a2</li>
<li id="a3">a3</li>
</ul>
父节点ul
包含三个子节点li
,在父节点上绑定一个事件侦听器,让ul
委托所有节点的事件侦听。
我的期望:
当您单击a1
时,show1
函数将删除ID为a2
的同级事件监听器。
也就是说,单击ID为li
的{{1}}后单击ID为a2
的{{1}},li
将不会显示在控制台上。
实际动作:
单击ID为a1
的{{1}}后,单击ID为ok2
的{{1}},li
将显示在控制台上。
为什么
a2
无法删除同级对象上的事件监听器?
如何解决?
答案 0 :(得分:2)
如果将侦听器附加到某个元素,则只能删除同一元素上的同一侦听器-您不能从子元素中删除该侦听器,因为它没有附加到子元素上
对于要寻找的功能,可以将要从中“删除”点击功能的节点添加到Set
中,然后在父节点的处理程序中检查event.target
(flag
变量)不包含在该Set
中:
const elementsToIgnore = new Set();
function show1() {
console.log("ok1");
elementsToIgnore.add(document.getElementById("a2"));
}
function show2() {
console.log("ok2");
}
function show3() {
console.log("ok3");
}
function delegate(event) {
var flag = event.target;
if (elementsToIgnore.has(flag)) return;
switch (flag.id) {
case "a1":
show1();
break;
case "a2":
show2();
break;
case "a3":
show3();
break;
}
}
ob = document.getElementById("tl");
ob.addEventListener("click", delegate);
<ul id="tl">
<li id="a1">a1</li>
<li id="a2">a2</li>
<li id="a3">a3</li>
</ul>
答案 1 :(得分:1)
这是您要将事件侦听器添加到ul
而不是li
的信标。将event
处理程序添加到li
中,如下所示:
function show1(){
console.log("ok1");
document.getElementById("a2").removeEventListener("click",delegate);
}
function show2(){
console.log("ok2");
}
function show3(){
console.log("ok3");
}
function delegate(event)
{
var flag = event.target;
switch(flag.id){
case "a1":
show1();
break;
case "a2":
show2();
break;
case "a3":
show3();
break;
}
}
ob = document.getElementsByTagName("li");
for(let i=0; i<ob.length; i++){
ob[i].addEventListener("click",delegate);
}
<ul id="tl">
<li id="a1">a1</li>
<li id="a2">a2</li>
<li id="a3">a3</li>
</ul>