Ruby on Rails中Bootstrap下拉菜单切换页面后失效问题求助
Rails + Bootstrap 5.3 导航栏下拉菜单跳转后失效问题
问题情况
用Ruby on Rails搭配Bootstrap 5.3搭建个人项目展示网站,导航栏代码放在头部布局文件中。出现以下异常:
- 点击下拉菜单里的项目链接跳转页面后,导航栏的下拉按钮直接失效,点击无反应
- 点击导航栏里非下拉的链接(比如「About Me」)跳转则完全正常
- 刷新失效页面后,下拉菜单功能又恢复正常
相关代码
<nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container-fluid"> <a class="navbar-brand">Title</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNavDropdown"> <ul class="navbar-nav"> <li class="nav-item"> <%= link_to "Home", root_path, class:"nav-link"%> </li> <li class="nav-item"> <%= link_to "About Me", home_about_path, class:"nav-link" %> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> Projects </a> <ul class="dropdown-menu"> <%= link_to "Living Atlas", projects_livingatlas_path, class:"dropdown-item" %> <%= link_to "Spreadsheet", projects_spreadsheet_path, class:"dropdown-item" %> <%= link_to "Yelp Review Manager", projects_yelp_path, class:"dropdown-item" %> <%= link_to "Ext2 File System", projects_ext2_path, class:"dropdown-item" %> <%= link_to "Personal Website", projects_website_path, class:"dropdown-item" %> </ul> </li> </ul> </div> </div> </nav>
原因分析
这是Rails默认启用的Turbo导致的问题:Turbo在页面跳转时采用局部刷新(只更新页面内容区域,不重新加载整个页面),而Bootstrap的下拉组件是在页面首次加载时初始化的。当下拉链接跳转后,Turbo没有触发Bootstrap组件的重新初始化,所以下拉按钮就失效了。
解决办法
方法1:禁用下拉链接的Turbo局部刷新
给下拉菜单里的所有link_to添加data: { turbo: false }属性,让这些链接跳转时触发全页刷新,这样Bootstrap组件会重新初始化:
<ul class="dropdown-menu"> <%= link_to "Living Atlas", projects_livingatlas_path, class:"dropdown-item", data: { turbo: false } %> <%= link_to "Spreadsheet", projects_spreadsheet_path, class:"dropdown-item", data: { turbo: false } %> <%= link_to "Yelp Review Manager", projects_yelp_path, class:"dropdown-item", data: { turbo: false } %> <%= link_to "Ext2 File System", projects_ext2_path, class:"dropdown-item", data: { turbo: false } %> <%= link_to "Personal Website", projects_website_path, class:"dropdown-item", data: { turbo: false } %> </ul>
方法2:监听Turbo事件重新初始化Bootstrap下拉
在app/javascript/application.js中添加代码,监听Turbo的turbo:load事件,每次页面加载(包括Turbo跳转后的局部加载)时重新初始化所有下拉组件:
document.addEventListener('turbo:load', function() { // 找到所有带下拉触发属性的元素,重新初始化 document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(el => { new bootstrap.Dropdown(el); }); });
方法3:全局配置Turbo兼容Bootstrap
如果不想逐个给链接加属性,也可以在Turbo配置中让所有导航链接触发全页刷新(此方式会失去Turbo局部刷新的优势,仅推荐小站点使用):
// 在application.js中添加 document.addEventListener('turbo:click', function(e) { if (e.target.closest('.nav-link')) { e.preventDefault(); window.location.href = e.target.href; } });
内容的提问来源于stack exchange,提问作者flavalv
相关产品推荐
相关产品推荐

