fix: back button navigation — guard hash setting during route()
When the back button triggers hashchange -> route(), the isRouting flag prevents navigate() and showDetail() from re-setting location.hash, which was creating duplicate history entries and trapping the user. Now the back button properly traverses history.
This commit is contained in:
+15
-8
@@ -63,6 +63,7 @@ async function init() {
|
||||
}
|
||||
|
||||
function route() {
|
||||
isRouting = true;
|
||||
const hash = location.hash.slice(1) || 'library';
|
||||
if (hash.startsWith('protocols/')) {
|
||||
showDetail(hash.split('/')[1]);
|
||||
@@ -81,14 +82,15 @@ function route() {
|
||||
} else {
|
||||
navigate('library');
|
||||
}
|
||||
isRouting = false;
|
||||
}
|
||||
|
||||
let searchTimer = null;
|
||||
let currentRoute = '';
|
||||
let isRouting = false;
|
||||
|
||||
function navigate(view) {
|
||||
// Prevent double navigation from hashchange
|
||||
if (currentRoute === view) return;
|
||||
if (currentRoute === view && view !== 'library') return;
|
||||
currentRoute = view;
|
||||
document.querySelectorAll('.view').forEach(v => v.style.display = 'none');
|
||||
document.getElementById('view-' + view).style.display = 'block';
|
||||
@@ -96,11 +98,17 @@ function navigate(view) {
|
||||
document.querySelectorAll('.mobile-panel a').forEach(a => a.classList.toggle('active', a.dataset.view === view));
|
||||
closeMenu();
|
||||
updateBreadcrumb(view);
|
||||
if (view === 'library') { location.hash = 'library'; loadProtocols(); }
|
||||
if (view === 'collections') { location.hash = 'collections'; loadCollections(); }
|
||||
if (!isRouting) {
|
||||
if (view === 'library') { location.hash = 'protocols'; }
|
||||
if (view === 'collections') { location.hash = 'collections'; }
|
||||
if (view === 'about') { location.hash = 'about'; }
|
||||
if (view === 'terms') { location.hash = 'terms'; }
|
||||
}
|
||||
if (view === 'library') loadProtocols();
|
||||
if (view === 'collections') loadCollections();
|
||||
if (view === 'create') { editingSlug = null; resetForm(); }
|
||||
if (view === 'create-collection') { editingCollectionSlug = null; resetCollectionForm(); }
|
||||
if (view === 'about') { location.hash = 'about'; }
|
||||
if (view === 'about') updateAboutPage();
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
@@ -313,7 +321,7 @@ function renderProtocolGrid(protocols) {
|
||||
|
||||
// --- Detail ---
|
||||
async function showDetail(slug) {
|
||||
if (location.hash !== '#protocols/' + slug) location.hash = 'protocols/' + slug;
|
||||
location.hash = 'protocols/' + slug;
|
||||
document.querySelectorAll('.view').forEach(v => v.style.display = 'none');
|
||||
document.getElementById('view-detail').style.display = 'block';
|
||||
document.querySelectorAll('header nav a').forEach(a => a.classList.remove('active'));
|
||||
@@ -713,7 +721,7 @@ async function saveCollection(e) {
|
||||
}
|
||||
|
||||
async function showCollectionDetail(slug) {
|
||||
if (location.hash !== '#collections/' + slug) location.hash = 'collections/' + slug;
|
||||
location.hash = 'collections/' + slug;
|
||||
document.querySelectorAll('.view').forEach(v => v.style.display = 'none');
|
||||
document.getElementById('view-collection-detail').style.display = 'block';
|
||||
document.querySelectorAll('header nav a').forEach(a => a.classList.remove('active'));
|
||||
@@ -786,7 +794,6 @@ async function deleteCollection(slug) {
|
||||
|
||||
// --- User Profile ---
|
||||
async function showUser(username) {
|
||||
if (location.hash !== '#users/' + username && location.hash !== '#user/' + username) location.hash = 'users/' + username;
|
||||
document.querySelectorAll('.view').forEach(v => v.style.display = 'none');
|
||||
document.getElementById('view-detail').style.display = 'block';
|
||||
document.querySelectorAll('header nav a').forEach(a => a.classList.remove('active'));
|
||||
|
||||
Reference in New Issue
Block a user