如何在可点击行内添加销毁按钮并解决事件冲突问题?
问题:可点击列表行内的删除按钮行为冲突
我想要实现一个可点击的列表行,同时在行内包含一个删除按钮。点击删除按钮时,确认提示框正常弹出,但之后会直接跳转到行链接对应的页面,并未删除记录。相关代码如下:
<li> <%= link_to project_path(@project) do %> ...truncated <%= @project.name %> ...truncated <%= button_to @project, method: :delete, data: { confirm: @confirm } do %> <%= 'Delete' %> <% end %> <% end %> </li>
我尝试添加onclick: "event.stopPropagation();"后,记录可以被删除,但确认对话框不再显示。是否可以在不自定义UJS/turbo/hotwire之外的内容的前提下解决该问题?
解决方案
核心原因
你的代码违反了HTML规范——<a>标签(由link_to生成)不能嵌套交互元素(如button_to生成的表单按钮),这会导致事件冒泡冲突:点击删除按钮时,既触发了删除的确认逻辑,又触发了外层链接的跳转。
可行解决方法(无需自定义UJS/Turbo代码)
方法1:调整DOM结构(推荐)
将删除按钮移到外层链接之外,通过CSS控制布局让它显示在行内,从根源避免嵌套冲突:
<li> <div class="row-content"> <%= link_to project_path(@project) do %> ...truncated <%= @project.name %> ...truncated <% end %> </div> <%= button_to @project, method: :delete, data: { confirm: @confirm } do %> <%= 'Delete' %> <% end %> </li>
搭配简单的CSS实现横向布局:
li { display: flex; align-items: center; justify-content: space-between; }
方法2:用链接代替按钮并修正事件逻辑
如果必须保留视觉上的嵌套布局,将button_to换成link_to(生成<a>标签),并添加精准的事件阻止逻辑,确保确认提示正常触发后再阻止外层链接的跳转:
<li> <%= link_to project_path(@project) do %> ...truncated <%= @project.name %> ...truncated <%= link_to 'Delete', @project, method: :delete, data: { confirm: @confirm }, onclick: "event.stopPropagation();" %> <% end %> </li>
注:这种方法虽能临时解决问题,但存在HTML语义冲突(链接嵌套链接),长期维护更推荐方法1。
内容的提问来源于stack exchange,提问作者Frexuz
相关产品推荐
相关产品推荐

