1 回答
TA贡献1851条经验 获得超3个赞
如果要将此代码包含在 末尾的 中,则可能不需要侦听该事件。为什么?在第一次加载时,浏览器将能够查询位于脚本元素之前的任何元素。在 Turbolinks 上,加载脚本时将有权访问页面上所有呈现的元素。<script><body>turbolinks:load<body>
值得补充的是,通过调用 body 元素,侦听器将在每次后续页面加载时调用,而不仅仅是在呈现脚本的页面上。如果后续页面加载中不存在这些元素,您将看到该错误。更重要的是,如果你在多个页面上包含脚本,那么监听器就会一次又一次地重复,这可能不是你想要的!document.addEventListener("turbolinks:load", …)<script>#nav-tabquerySelector
因此,解决问题的第一步是删除事件侦听器。我们将你的代码包装在一个立即调用的函数中,以防止污染全局范围:
;(function() {
let url = location.href.replace(/\/$/, "");
if (location.hash) {
const hash = url.split("#");
document.querySelector('#nav-tab a[href="#'+hash[1]+'"]').Tab.show();
url = location.href.replace(/\/#/, "#");
history.replaceState(null, null, url);
setTimeout(() => {
window.scrollTo(0,0);
}, 400);
}
})();
接下来要知道的是,Turbolinks管理自己的访问页面缓存,因此当用户点击“返回”时,将从此缓存中呈现页面。为此,它有一个系统可以添加到浏览器自己的堆栈中。如果您绕过Turbolinks系统,并自己调用(或),那么您最终可能会破坏“返回”导航。Turbolinks没有记录在案的手动添加到其历史记录堆栈的方法,但您可以尝试以下操作:historyhistory.replaceStatehistory.pushState
;(function() {
let url = location.href.replace(/\/$/, "");
if (location.hash) {
const hash = url.split("#");
document.querySelector('#nav-tab a[href="#'+hash[1]+'"]').Tab.show();
url = location.href.replace(/\/#/, "#");
Turbolinks
.controller
.replaceHistoryWithLocationAndRestorationIdentifier(url, Turbolinks.uuid())
setTimeout(() => {
window.scrollTo(0,0);
}, 400);
}
})();
请注意,这是未记录的,因此可能不会在将来的版本中公开提供。
最后,可能值得考虑将此代码段包含在主应用程序 JavaScript 捆绑包中,并将其加载到而不是正文中。在这种情况下,您需要使用'turbolinks:load处理程序。它可能看起来像这样:<head>
document.addEventListener('turbolinks:load', function () {
let url = location.href.replace(/\/$/, "");
const hash = url.split("#");
const navLink = document.querySelector('#nav-tab a[href="#'+hash[1]+'"]')
if (location.hash && navLink) {
navLink.Tab.show();
url = location.href.replace(/\/#/, "#");
Turbolinks
.controller
.replaceHistoryWithLocationAndRestorationIdentifier(url, Turbolinks.uuid())
setTimeout(() => {
window.scrollTo(0,0);
}, 400);
}
});
添加回答
举报