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

如何在可点击行内添加销毁按钮并解决事件冲突问题?

问题:可点击列表行内的删除按钮行为冲突

我想要实现一个可点击的列表行,同时在行内包含一个删除按钮。点击删除按钮时,确认提示框正常弹出,但之后会直接跳转到行链接对应的页面,并未删除记录。相关代码如下:

<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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:43:24