Я создал 5 разных HTML-страниц. У меня есть главная страница и раздел контента, в который будут динамически загружаться различные страницы, чтобы они выглядели как SPA. У меня есть этот JS-код, который работает почти правильно.
Код: Выделить всё
document.addEventListener('DOMContentLoaded', () => {
const navLinks = document.querySelectorAll('.nav-link');
const contentSection = document.querySelector('#content');
let currentPageIndex = 0;
let isFetching = false;
let ignoreScrollEvents = false;
const pages = [
{ id: 'nav-home', href: 'index.html', title: 'Home' },
{ id: 'nav-about', href: 'about.html', title: 'About' },
{ id: 'nav-gallery', href: 'gallery.html', title: 'Gallery' },
{ id: 'nav-services', href: 'services.html', title: 'Services' },
{ id: 'nav-contact', href: 'contact.html', title: 'Contact' }
];
const loadPageContent = async (url, append = false, prepend = false) => {
try {
const response = await fetch(url);
if (!response.ok) throw new Error('Network response was not ok');
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newContent = doc.querySelector('#content');
if (newContent) {
const section = document.createElement('div');
section.classList.add('content-section');
section.innerHTML = newContent.innerHTML;
if (append) {
contentSection.appendChild(section);
} else if (prepend) {
const previousScrollHeight = document.documentElement.scrollHeight;
contentSection.insertBefore(section, contentSection.firstChild);
const newScrollHeight = document.documentElement.scrollHeight;
window.scrollBy(0, newScrollHeight - previousScrollHeight); // Adjust scroll position to maintain view
} else {
contentSection.innerHTML = section.innerHTML;
window.scrollTo(0, 0); // Scroll to top when navigating via navbar
}
} else {
console.warn('Failed to find the #content section in the fetched HTML');
}
} catch (error) {
console.warn('Failed to load content:', error);
} finally {
isFetching = false;
}
};
const handleNavigation = async (index, append = false, prepend = false) => {
if (index < 0 || index >= pages.length) return;
if (isFetching) return;
isFetching = true;
currentPageIndex = index;
const page = pages[currentPageIndex];
await loadPageContent(page.href, append, prepend);
navLinks.forEach(nav => nav.classList.remove('active'));
document.querySelector(`a[href="${page.href}"]`).classList.add('active');
};
const handleNavClick = async (event) => {
event.preventDefault();
const url = event.currentTarget.getAttribute('href');
const pageIndex = pages.findIndex(page => page.href === url);
// Temporarily ignore scroll events to prevent interference
ignoreScrollEvents = true;
// Handle navigation and then re-enable scroll events after a delay
await handleNavigation(pageIndex);
setTimeout(() => {
ignoreScrollEvents = false;
}, 500);
};
const handleScroll = async () => {
if (isFetching || ignoreScrollEvents) return;
const scrolledToBottom = (window.innerHeight + window.scrollY) >= (document.documentElement.scrollHeight - 1);
const scrolledToTop = window.scrollY === 0;
if (scrolledToBottom && currentPageIndex < pages.length - 1) {
await handleNavigation(currentPageIndex + 1, true, false);
} else if (scrolledToTop && currentPageIndex > 0) {
await handleNavigation(currentPageIndex - 1, false, true);
}
};
navLinks.forEach(link => link.addEventListener('click', handleNavClick));
window.addEventListener('scroll', handleScroll);
// Initial load
ignoreScrollEvents = true;
handleNavigation(0).then(() => {
ignoreScrollEvents = false;
});
});
Подробнее здесь: https://stackoverflow.com/questions/785 ... a-work-lik