Скрипт для прокрутки и навигации, чтобы многостраничное приложение (MPA) работало как одностраничное приложение (SPA)?Jquery

Программирование на jquery
Ответить Пред. темаСлед. тема
Anonymous
 Скрипт для прокрутки и навигации, чтобы многостраничное приложение (MPA) работало как одностраничное приложение (SPA)?

Сообщение Anonymous »

Я создаю статический веб-сайт. Я хочу создать MPA, но ощутить SPA для лучшего SEO и удобства пользователей. Я только начинающий UI/UX-разработчик и хочу создать простой веб-сайт. Я бы предпочел, чтобы сценарий обрабатывал эту функцию загрузки и прокрутки, чтобы сделать функцию MPA похожей на SPA.
Я создал 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;
});
});

С этим кодом есть некоторые проблемы. На самом деле он ведет себя как SPA, если только использовать прокрутку, но если я использую навигацию по клику, прокрутка не работает должным образом. Также возникают некоторые проблемы при прокрутке назад. Мне бы также хотелось, чтобы активные классы могли идеально переключаться.

Подробнее здесь: https://stackoverflow.com/questions/785 ... a-work-lik
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Сеанс в Spring Security с аутентификацией LDAP для SPA (одностраничное приложение)
    Anonymous » » в форуме JAVA
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • Opencart 4 и SPA. Можно ли интегрировать приложение SPA в Opencart?
    Anonymous » » в форуме Php
    0 Ответы
    31 Просмотры
    Последнее сообщение Anonymous
  • Как я могу быть уверен, что все мои ссылки в моем SPA удерживают пользователя в моем SPA?
    Anonymous » » в форуме Php
    0 Ответы
    46 Просмотры
    Последнее сообщение Anonymous
  • Одностраничное приложение ASP.NET MVC — сохранение URL-адреса «#» в контактной форме POST
    Anonymous » » в форуме C#
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Одностраничное приложение ASP.NET MVC — сохранение URL-адреса «#» в контактной форме POST
    Anonymous » » в форуме C#
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Jquery»