mirror of
https://github.com/litruv/Docs-Viewer.git
synced 2026-07-24 02:36:07 +10:00
Refactor scrolling behavior and enhance hash navigation handling
This commit is contained in:
@@ -5,12 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||
<title>Litruv</title>
|
||||
|
||||
<meta name="description" content="Documentation for Litruv's tools and projects">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:description" content="Documentation for Litruv's tools and projects">
|
||||
<meta property="og:url" content="">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:description" content="Documentation for Litruv's tools and projects">
|
||||
<!--ogmetadata-->
|
||||
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
|
||||
|
||||
56
index.js
56
index.js
@@ -82,8 +82,10 @@ class DOMService {
|
||||
fileIndex: document.getElementById('file-index'),
|
||||
titleText: document.querySelector('.title-text .page-title'),
|
||||
leftSidebar: document.querySelector('.left-sidebar'),
|
||||
menuButton: document.querySelector('.menu-button')
|
||||
menuButton: document.querySelector('.menu-button'),
|
||||
header: document.querySelector('title-bar') // Add header element
|
||||
};
|
||||
this.headerOffset = 60; // Fixed header heightfsetHeight || 0; // Get header height
|
||||
}
|
||||
|
||||
setupMobileMenu() {
|
||||
@@ -222,6 +224,18 @@ class DOMService {
|
||||
});
|
||||
}
|
||||
|
||||
scrollToElement(element) {
|
||||
if (!element) return;
|
||||
const rect = element.getBoundingClientRect();
|
||||
const absoluteElementTop = rect.top + window.scrollY;
|
||||
const middle = absoluteElementTop - (this.headerOffset + 20); // Add extra padding
|
||||
|
||||
window.scrollTo({
|
||||
top: middle,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
|
||||
createOutlineLink(heading) {
|
||||
const link = document.createElement('a');
|
||||
link.href = `${window.location.pathname}${window.location.search}#${heading.id}`;
|
||||
@@ -231,7 +245,7 @@ class DOMService {
|
||||
link.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
history.pushState(null, '', link.href);
|
||||
heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
this.scrollToElement(heading);
|
||||
heading.classList.remove('highlight');
|
||||
void heading.offsetWidth;
|
||||
heading.classList.add('highlight');
|
||||
@@ -444,7 +458,8 @@ class NavigationService {
|
||||
window.addEventListener('popstate', async () => {
|
||||
const slug = new URLSearchParams(window.location.search).toString()
|
||||
.replace(/^=/, '').replace(/^\?/, '');
|
||||
this.eventBus.emit('navigation:requested', { slug });
|
||||
const hash = window.location.hash;
|
||||
this.eventBus.emit('navigation:requested', { slug, hash });
|
||||
});
|
||||
|
||||
document.addEventListener('click', async (e) => {
|
||||
@@ -510,9 +525,30 @@ class Documentation {
|
||||
this.indexData.documents.forEach(doc =>
|
||||
this.domService.createFileIndexItem(doc, this.domService.elements.fileIndex));
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const slug = urlParams.get('') || urlParams.get('page') || 'welcome';
|
||||
// Use defaultPage from index.json
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
let slug = '';
|
||||
if (params.has('')) {
|
||||
slug = params.get('');
|
||||
} else {
|
||||
for (const [key] of params) {
|
||||
slug = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
slug = slug || this.indexData.defaultPage;
|
||||
|
||||
await this.loadDocumentBySlug(slug);
|
||||
|
||||
// Handle hash after load using DOMService's scrollToElement
|
||||
if (window.location.hash) {
|
||||
setTimeout(() => {
|
||||
const element = document.getElementById(window.location.hash.slice(1));
|
||||
if (element) {
|
||||
this.domService.scrollToElement(element);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
} catch (error) {
|
||||
this.domService.setError(`Failed to load documentation index: ${error.message}`);
|
||||
}
|
||||
@@ -555,7 +591,17 @@ class Documentation {
|
||||
|
||||
window._currentPath = path;
|
||||
|
||||
// Handle hash scrolling after content is loaded
|
||||
if (window.location.hash) {
|
||||
const element = document.getElementById(window.location.hash.slice(1));
|
||||
if (element) {
|
||||
setTimeout(() => {
|
||||
this.domService.scrollToElement(element);
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
} catch (error) {
|
||||
this.domService.setError('Error loading document. Please try again.');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user