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

Rails 7 + Turbo环境下子菜单点击链接时闪烁问题求助

问题:Rails 7 + Turbo 下子菜单点击链接时其他子菜单闪烁的解决办法

我基于 Rails 7、Bootstrap 5 和 jQuery 实现了一个可切换的子菜单:点击按钮展开对应子菜单,同时自动收起其他子菜单。但测试时发现,点击子菜单内的链接(控制器加了3秒延迟模拟慢加载),其他子菜单会出现持续3秒的闪烁,禁用 Turbo 后问题消失。

原实现代码

HTML

<div>
  <button class="toggle-submenu">Sales</button>
  <div class="submenu">
    <ul>
      <li><a href="/sales/recent">Recent</a></li>
      <li><a href="/sales">All</a></li>
    </ul>
  </div>
</div>
<div>
  <button class="toggle-submenu">Products</button>
  <div class="submenu">
    <ul>
      <li><a href="/products">All</a></li>
    </ul>
  </div>
</div>

CSS

.submenu {
  height: 0;
  overflow: hidden;
}

.submenu-open {
  height: auto;
}

JavaScript

$(document).on('click', '.toggle-submenu', function() {
    $(this).parent().find('.submenu').toggleClass('submenu-open');
    $('.submenu').not($(this).parent().find('.submenu')).removeClass('submenu-open');
});

解决方案

问题根源在于 Turbo 在导航过程中会保留/修改 DOM 状态,导致菜单的显示逻辑出现异常,以下是几种可行的解决方式:

1. 导航前重置菜单状态

监听 Turbo 的请求发起事件,在页面开始加载前主动收起所有子菜单,避免状态混乱:

$(document).on('turbo:before-fetch-request', function() {
  $('.submenu').removeClass('submenu-open');
});

2. 标记菜单为永久保留元素

给菜单的外层容器添加 data-turbo-permanent 属性,让 Turbo 在页面置换时保留该容器及其状态,不会重新渲染菜单部分:

<div data-turbo-permanent>
  <div>
    <button class="toggle-submenu">Sales</button>
    <div class="submenu">...</div>
  </div>
  <div>
    <button class="toggle-submenu">Products</button>
    <div class="submenu">...</div>
  </div>
</div>

3. 优化事件绑定逻辑

将菜单的点击事件绑定放在 Turbo 的页面加载事件中,确保每次页面置换后事件都能正确绑定,避免旧事件残留导致的异常:

$(document).on('turbo:load', function() {
  // 先移除旧绑定,避免重复触发
  $('.toggle-submenu').off('click');
  
  $('.toggle-submenu').on('click', function() {
    const targetSubmenu = $(this).parent().find('.submenu');
    targetSubmenu.toggleClass('submenu-open');
    $('.submenu').not(targetSubmenu).removeClass('submenu-open');
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:24:52