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

Ruby on Rails项目中AJAX绑定的卡片点击事件需多次点击才触发如何优化

问题根因
  • 事件绑定时机错误:你将.card的点击事件绑定放在了.show链接的ajax:success回调中,第一次点击Details链接只会触发AJAX请求,此时点击事件还未完成绑定,不会触发展开逻辑。只有等AJAX请求成功、事件绑定完成后,后续的点击才会生效,这就是需要多次点击才能触发的核心原因。卡片展开后点击可以单次收回,也是因为此时事件已经绑定完成。
  • 重复绑定风险:每次触发ajax:success都会重新给所有.card绑定一次点击事件,多次请求后会出现单次点击执行多次切换逻辑的问题,反而会出现点击后看似无响应的异常。
  • 触发范围不匹配:你的需求是点击Details链接触发展开,但你绑定的是整个卡片的点击事件,触发范围和预期不符。
修复方案

如果卡片的隐藏附加文本已经提前渲染在页面中(默认设置为display: none),推荐使用纯前端实现,无需发起额外AJAX请求:

  1. 修改ERB链接代码,去掉不需要的remote: true配置:
<div class='card-buttons'>
  <%= link_to 'Details', 'javascript:void(0)', class: 'card-link show' %>
  <%= link_to 'Edit', edit_cocktail_path(cocktail), class: 'card-link' %>
  <%= link_to 'Remove', cocktail, class: 'card-link', method: :delete, data: { confirm: 'Are you sure?', remote: true }, class: 'delete' %>
</div>
  1. 将原show.js.erb中的逻辑迁移到全局JS文件(如app/assets/javascripts/cards.js),使用事件委托仅绑定一次即可全局生效:
$(document).ready(function() {
  // 事件委托绑定,兼容静态渲染和后续动态加载的卡片,仅绑定一次不会重复
  $(document).on('click', '.card .show', function(e) {
    e.preventDefault();
    // 获取当前点击链接所属的卡片
    const $currentCard = $(this).closest('.card');
    clickToExpandCards($currentCard);
  });

  function clickToExpandCards($obj){
    if ($obj.hasClass('card-expand')) { 
      $obj.find('.card-hidden-text').hide();
      $obj.removeClass('card-expand'); 
    } else {
      $obj.find('.card-hidden-text').show();
      $obj.addClass('card-expand');
    }
  };
});

如果隐藏内容确实需要从服务端动态加载,可按如下方案调整:

  1. 保留ERB链接的remote: true配置:
<%= link_to 'Details', cocktail, class: 'card-link show', remote: true %>
  1. 修改show.js.erb逻辑,无需额外绑定点击事件,请求成功后直接操作对应卡片即可:
// 定位当前请求对应的卡片
const $currentCard = $('a.show[href="<%= cocktail_path(@cocktail) %>"]').closest('.card');
// 插入服务端返回的详情内容,可根据实际业务调整渲染逻辑
$currentCard.find('.card-hidden-text').html('<%= j render "cocktail_details", cocktail: @cocktail %>');
// 切换展开状态
if ($currentCard.hasClass('card-expand')) { 
  $currentCard.find('.card-hidden-text').hide();
  $currentCard.removeClass('card-expand'); 
} else {
  $currentCard.find('.card-hidden-text').show();
  $currentCard.addClass('card-expand');
}

内容的提问来源于stack exchange,提问作者Drew Peterson 7671

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:27:03