RoR中Bootstrap移动端侧边栏导航Turbolinks切换页面失效求助
解决Turbolinks跳转后Bootstrap侧边栏失效的问题
这个问题我太熟悉了——Turbolinks的核心特性就是不刷新整个页面,仅通过AJAX替换页面内容,这就导致你原来绑定在window.onload上的初始化代码,只有第一次打开页面时会执行,通过链接跳转后根本不会触发,侧边栏自然就失效了。另外我还发现你代码里有个小bug,也会影响功能,一起给你修正:
问题根源
- Turbolinks事件不兼容:
window.onload仅在页面完全刷新时触发,Turbolinks跳转不会触发这个事件,所以侧边栏的初始化逻辑没机会重新执行。 - jQuery选择器错误:你代码里的
$("sidebarNavigation")、$("sideMenu")、$("navbar-toggle")这些选择器都缺少了.(类选择器前缀),jQuery根本找不到对应的元素,功能自然不正常。 - 重复DOM元素:每次初始化时都会克隆sideMenu和添加overlay,跳转后不清理的话,页面会有多个重复元素,导致交互冲突。
修改后的sidebarNav.js代码
// 使用Turbolinks的turbolinks:load事件,替代window.onload document.addEventListener('turbolinks:load', function() { if (window.jQuery) { $(document).ready(function() { // 先清理旧的侧边栏和遮罩,避免重复创建 $(".sideMenu, .overlay").remove(); // 克隆导航栏并创建侧边菜单 $(".sidebarNavigation .navbar-collapse") .hide() .clone() .appendTo("body") .removeAttr("class") .addClass("sideMenu") .show(); // 添加遮罩层 $("body").append("<div class='overlay'></div>"); // 绑定导航按钮点击事件(修正选择器) $(".navbar-toggle").on("click", function() { var sidebarClass = $(".sidebarNavigation").attr("data-sidebarClass"); $(".sideMenu").addClass(sidebarClass); $(".sideMenu, .overlay").toggleClass("open"); }); // 绑定遮罩层点击关闭事件 $(".overlay").on("click", function() { $(this).removeClass("open"); $(".sideMenu").removeClass("open"); }); // 窗口大小变化时的处理(修正选择器) $(window).resize(function() { if ($(".navbar-toggle").is(":hidden")) { $(".sideMenu, .overlay").hide(); } else { $(".sideMenu, .overlay").show(); } }); }); } else { console.log("sidebarNavigation requires jQuery"); } });
关键改动说明
- 替换事件绑定:用
document.addEventListener('turbolinks:load', ...)替代window.onload,确保每次Turbolinks跳转后都会重新初始化侧边栏。 - 清理旧元素:在初始化前先移除
.sideMenu和.overlay,避免页面中存在多个重复元素导致交互异常。 - 修正选择器:所有类选择器都加上了
.,比如.sidebarNavigation、.navbar-toggle,确保jQuery能正确找到DOM元素。 - 优化事件绑定:把遮罩层的点击事件移到导航按钮点击事件外面,避免每次点击按钮都重复绑定事件。
额外建议
- 确保你的Turbolinks版本是最新的,避免一些已知的兼容性问题。
- 可以把这个初始化逻辑封装成一个函数,方便在需要的时候手动调用(比如某些动态加载内容后)。
内容的提问来源于stack exchange,提问作者Steven Smith
相关产品推荐
相关产品推荐

