You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:36:21