JS中stopPropagation阻止子元素触发父点击事件失效问题
问题现象
- 待办项设计交互逻辑:
- 用户输入待办内容按回车后,内容渲染为独立div元素
- 点击待办div时,待办文本添加
line-through删除线标记完成 - 鼠标悬停在待办div上时,div内部显示带垃圾桶图标的删除按钮子元素
- 异常表现:点击子元素删除图标时,父div的点击事件仍会触发,待办文本被错误加上删除线,在删除按钮的点击回调中调用
event.stopPropagation()阻止事件冒泡未生效 - 异常效果参考:

原代码问题根因
- 给删除按钮绑定点击事件时第三个参数传了
true,代表事件在捕获阶段触发。而父div的onclick事件默认在冒泡阶段触发,捕获阶段调用stopPropagation()只能阻断捕获阶段的事件传播,无法阻止后续冒泡阶段父元素的事件响应。 - 删除按钮的创建、事件绑定逻辑全部写在父div的
onmouseover回调中,鼠标在div上移动时会反复触发mouseover,重复创建删除按钮、重复绑定事件,既造成DOM冗余,也会导致事件触发逻辑混乱。
修复后代码
let text_field = document.getElementById("fname"); let count = 0; text_field.addEventListener("keypress", function(event) { if(event.key === "Enter") { count++; event.preventDefault(); // 创建待办项div let block_to_insert = document.createElement('div'); block_to_insert.id = "div-created"+count; block_to_insert.classList.add('todo-div-todo'); block_to_insert.textContent = text_field.value; // 提前创建删除按钮,不要放在mouseover里重复创建 let delete_div = document.createElement('div'); delete_div.classList.add('delete-todo'); delete_div.innerHTML = '<i class="fa-solid fa-trash" style="color:white"></i>'; delete_div.style.display = 'none'; // 默认隐藏 block_to_insert.appendChild(delete_div); // 父待办项点击事件:切换删除线 block_to_insert.onclick = function(e){ // 双重保险:排除点击目标是删除按钮的情况 if(e.target === delete_div || delete_div.contains(e.target)) return; block_to_insert.style.setProperty("text-decoration", "line-through"); } // 悬停显示/隐藏删除按钮,用mouseenter/mouseleave避免子元素触发重复事件 block_to_insert.onmouseenter = function(){ delete_div.style.display = 'block'; } block_to_insert.onmouseleave = function(){ delete_div.style.display = 'none'; } // 删除按钮点击事件:移除第三个参数true,在冒泡阶段触发 delete_div.addEventListener('click',function (event){ event.stopPropagation(); // 此时阻止冒泡可正常拦截父元素事件 event.preventDefault(); block_to_insert.remove(); // 补充删除待办项的实际逻辑 }); // 插入待办项到页面 let where_to_insert = document.getElementById('outer-div'); where_to_insert.appendChild(block_to_insert); // 清空输入框 text_field.value = ''; } });
内容的提问来源于stack exchange,提问作者Artani
相关产品推荐
相关产品推荐

