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

为.details ul li设置事件委托时删除操作失效,原因是什么?

事件委托绑定在li上失效的原因分析

问题描述

当把事件委托绑定在.details ul上时,点击p标签的删除操作可正常执行;但改为绑定在.details ul li上时,删除操作失效。为什么p标签的点击事件无法触发绑定在li上的委托逻辑?

相关代码

JavaScript

$(function() {
  $('.btn').click(function() {
    if ($('.message').val()) {
      var li = $('<li></li>');
      li.html($('.message').val() + '<p>删除</p>');
      $('ul').prepend(li);
      li.slideDown();
      $('.message').val("");
    }
  })
  // 绑定在ul上有效,换成$('.details ul li').on(...)则失效
  $('.details ul').on('click', 'p', function() {
    $(this).parent().remove();
  })
})

CSS

* {
  padding: 0;
  margin: 0;
}

li {
  list-style: none;
}

.main {
  margin: 50px auto;
  overflow: hidden;
  border: 1px solid black;
  padding: 10px;
  width: 560px;
}

.message {
  margin-left: 5px;
  margin-right: 5px;
  width: 437px;
  height: 156px;
  border: 1px solid #ccc;
  outline: none;
  resize: none;
}

.info {
  margin-top: 140px;
}

.btn {
  margin-top: 140px;
}

.info,
.message,
.btn {
  float: left;
}

.details {
  margin-left: 70px;
  margin-top: 170px;
  width: 437px;
}

.details ul li {
  display: none;
  border-bottom: 1px dotted #ccc;
}

.details ul li p {
  float: right;
  color: red;
}

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
  <div class="info">微博发布</div>
  <textarea name="" class="message" cols="30" rows="10"></textarea>
  <input type="button" value="发布" class="btn">
  <div class="details">
    <ul>
      <li>hello
        <p>delete</p>
      </li>
    </ul>
  </div>
</div>

原因分析

核心问题出在事件委托的绑定逻辑和元素的动态性上:

  • 事件委托的本质是把事件绑定在一个静态存在的父元素上,利用事件冒泡机制捕获子元素的事件。
  • 当你用$('.details ul li').on('click', 'p', ...)绑定委托时,jQuery只会给页面初始化时已经存在的li元素添加委托逻辑。而你通过发布按钮新增的li是后续动态创建的,这些新li并没有被包含在初始选择器的集合里,所以它们无法监听内部p标签的点击事件。
  • 虽然p标签的点击事件确实会冒泡到父级li,但如果这个li是动态新增的,它本身从来没有被绑定过委托处理逻辑,自然不会触发删除操作。
  • 而绑定在.details ul上时,ul是页面加载就存在的静态元素,所有动态添加的li里的p点击事件都会冒泡到ul,ul上的委托逻辑能正确捕获到事件并执行删除。

另外补充:页面默认的那个li是display:none状态,即便能点击到它的p标签,绑定在它上面的委托是生效的,但动态生成的li没有这个委托,所以会出现“只有默认li能删(但看不到),新增的删不了”的现象。

解决方法

  1. 继续使用静态父元素作为委托载体(推荐,符合事件委托的最佳实践):
    保持原代码中绑定在.details ul上的逻辑即可。

  2. 动态创建li时绑定委托:
    如果一定要绑定在li上,需要在每次生成新li的时候,给它单独绑定委托:

    $('.btn').click(function() {
      if ($('.message').val()) {
        var li = $('<li></li>');
        li.html($('.message').val() + '<p>删除</p>');
        // 给新创建的li绑定委托
        li.on('click', 'p', function() {
          $(this).parent().remove();
        });
        $('ul').prepend(li);
        li.slideDown();
        $('.message').val("");
      }
    })
    

内容的提问来源于stack exchange,提问作者kittates

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:36:15