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

Ruby on Rails页面切换后响应式导航栏汉堡菜单功能失效问题

问题根因

你当前使用的是Rails框架默认集成的Turbo(旧版本称为TurboLinks),页面跳转时不会触发完整的页面重载,你代码中监听的DOMContentLoaded事件仅在首次进入站点时执行一次。跳转后导航栏DOM元素会被新内容替换,之前绑定在旧.burger-menu元素上的点击事件随着旧DOM被销毁而失效,新渲染的汉堡按钮没有绑定对应点击事件,所以点击无响应。

解决方案

推荐使用事件委托的方式绑定事件,不需要依赖页面加载事件,也不会出现重复绑定的问题:

// 把事件绑定在document上,点击时自动判断触发源是否为汉堡按钮
document.addEventListener('click', (e) => {
  const burgerBtn = e.target.closest('.burger-menu')
  if (!burgerBtn) return

  const responsiveMenu = document.querySelector('.responsive-navbar');
  const body = document.querySelector('body');
  const responsiveLinks = document.querySelectorAll('.responsive-menu-links')

  burgerBtn.classList.toggle('cross')
  responsiveMenu.classList.toggle('menu-open');
  body.classList.toggle('disable-scroll');
  responsiveLinks.forEach(link => {
    link.classList.toggle('trigger-anim')
  })
})

如果你不想修改原有事件绑定逻辑,也可以将原来的DOMContentLoaded事件替换为Turbo的专属加载事件,注意要提前移除旧事件避免重复绑定:

// 提前抽离事件处理函数
function bindBurgerMenu() {
  let responsiveMenu = document.querySelector('.responsive-navbar');
  let body = document.querySelector('body');
  let burgerBtn = document.querySelector('.burger-menu');
  // 先移除旧监听器,避免跳转后重复绑定
  burgerBtn.removeEventListener('click', handleBurgerClick)
  burgerBtn.addEventListener('click', handleBurgerClick)
}

function handleBurgerClick() {
  const burgerBtn = document.querySelector('.burger-menu')
  const responsiveMenu = document.querySelector('.responsive-navbar');
  const body = document.querySelector('body');
  const responsiveLinks = document.querySelectorAll('.responsive-menu-links')

  burgerBtn.classList.toggle('cross')
  responsiveMenu.classList.toggle('menu-open');
  body.classList.toggle('disable-scroll');
  responsiveLinks.forEach(link => {
    link.classList.toggle('trigger-anim')
  })
}

// 监听Turbo页面加载完成事件
document.addEventListener('turbo:load', bindBurgerMenu)
// 如果你用的是旧版Rails的TurboLinks,替换为监听 turbolinks:load 事件即可

额外优化建议

菜单打开状态下跳转页面时,body的disable-scroll类可能残留导致新页面无法滚动,可以监听Turbo跳转前事件清理菜单状态:

document.addEventListener('turbo:before-visit', () => {
  const burgerBtn = document.querySelector('.burger-menu')
  const responsiveMenu = document.querySelector('.responsive-navbar');
  const body = document.querySelector('body');
  const responsiveLinks = document.querySelectorAll('.responsive-menu-links')

  burgerBtn?.classList.remove('cross')
  responsiveMenu?.classList.remove('menu-open');
  body?.classList.remove('disable-scroll');
  responsiveLinks?.forEach(link => link.classList.remove('trigger-anim'))
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:36:04