Вопрос или проблема
У меня есть 2 страницы: index.html
и app.js
-
index.html
выглядит так<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="app.js" defer></script> <title>Банковское приложение</title> </head> <body> <!-- Здесь вы будете работать --> <div id="app">Загрузка...</div> <template id="login"> <h1>Банковское приложение</h1> <section> <a href="/dashboard">Войти</a> </section> </template> <template id="dashboard"> <header> <h1>Банковское приложение</h1> <a href="/login">Выйти</a> </header> <section> Баланс: 100$ </section> <section> <h2>Транзакции</h2> <table> <thead> <tr> <th>Дата</th> <th>Объект</th> <th>Сумма</th> </tr> </thead> <tbody></tbody> </table> </section> </template> </body> </html>
-
app.js
выглядит такconst routes = { '/login': { templateId: 'login' }, '/dashboard': { templateId: 'dashboard' }, }; function updateRoute() { const path = window.location.pathname; const route = routes[path] console.log(route.templateId) const template = document.getElementById(route.templateId); const view = template.content.cloneNode(true); const app = document.getElementById('app'); app.innerHTML = ''; app.appendChild(view); } updateRoute()
Когда я запускаю на локальном (живом) сервере в VS Code и перехожу по адресу localhost:5500/login
, я не получаю шаблон входа из index.html
Помогите, пожалуйста, узнать почему?
Проблема, с которой вы столкнулись, связана с тем, что браузер не обновляет содержимое страницы при изменении URL-адреса в адресной строке. Ваш код правильно определяет текущий путь и пытается обновить содержимое страницы, но это происходит только при первой загрузке страницы.
Чтобы решить эту проблему, нужно добавить обработчик событий для изменения URL-адреса и вызывать функцию updateRoute при каждом изменении. Вы можете использовать событие popstate, которое срабатывает при изменении истории браузера (например, при нажатии кнопок “назад” или “вперед”).
Ответ или решение
Ваша проблема связана с тем, что вы используете стандартные ссылки (<a href="/login">
) для перехода между маршрутами, что приводит к полной перезагрузке страницы, а это сбрасывает состояние вашего приложения на стороне клиента. Браузер загружает новую страницу, и ваш JavaScript код не получает возможность обработать изменение URL.
Для решения данной проблемы вы можете использовать history.pushState
для управления маршрутизацией на стороне клиента без перезагрузки страницы. Вот как это можно сделать:
-
Изменение обработчика ссылок: Замените стандартное поведение ссылок, добавив обработчик событий
click
, который будет вызыватьupdateRoute
. -
Добавление события popstate: Оно сработает, когда пользователь использует кнопку назад или вперед в браузере.
Вот обновленный код для вашего файла app.js
:
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard' },
};
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
if (route) {
const template = document.getElementById(route.templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
} else {
// Обработайте случай, когда маршрут не найден
console.error(`Маршрут ${path} не найден`);
}
}
function navigate(event) {
event.preventDefault(); // Остановить стандартное поведение ссылки
const path = event.target.getAttribute('href');
window.history.pushState({}, '', path); // Изменить URL без перезагрузки
updateRoute(); // Обновить содержимое страницы
}
// Привязываем обработчик событий ко всем ссылкам
document.addEventListener('DOMContentLoaded', () => {
const links = document.querySelectorAll('a[href]');
links.forEach(link => {
link.addEventListener('click', navigate);
});
// Обработчик события popstate
window.addEventListener('popstate', updateRoute);
updateRoute(); // Первоначальная загрузка контента
});
Объяснение изменений:
-
Функция
navigate
: Эта функция предотвращает стандартное поведение ссылки (перезагрузку страницы) и вместо этого обновляет URL с помощьюhistory.pushState
. Затем вызываетсяupdateRoute
, чтобы загрузить соответствующий шаблон. -
Событие
DOMContentLoaded
: Этот код привязывает обработчикclick
ко всем ссылкам в документе, инициализируя системы маршрутизации при загрузке страницы. -
Событие
popstate
: Это событие будет вызвано, когда пользователь нажимает кнопки "Назад" или "Вперед" в своем браузере, и оно обновляет содержимое страницы в соответствии с текущим URL.
Теперь, когда вы запустите ваше приложение на локальном сервере (например, localhost:5500/login
), вы сможете перемещаться между страницами без перезагрузки и загружать шаблоны, как и ожидалось.