Page.js — это клиентский маршрутизатор для JavaScript, который позволяет управлять навигацией на стороне браузера без полной перезагрузки страницы. По умолчанию Page.js перехватывает все внутренние ссылки, ведущие на текущий сайт, и обрабатывает их через маршруты. Однако ссылки, ведущие на внешние ресурсы, обычно не должны обрабатываться маршрутизатором, иначе это нарушит стандартное поведение браузера и приведёт к ошибкам навигации.
Чтобы игнорировать внешние ссылки, важно понять два ключевых аспекта: определение внешней ссылки и механизм фильтрации в Page.js.
Внешняя ссылка — это ссылка, домен которой отличается от текущего
документа. Проверка может выполняться с использованием объекта
URL:
function isExternalLink(href) {
const linkUrl = new URL(href, window.location.origin);
return linkUrl.origin !== window.location.origin;
}
Здесь window.location.origin возвращает протокол, домен
и порт текущего сайта. Если origin ссылки не совпадает с
текущим, она считается внешней. Такой подход универсален, учитывает
протоколы http, https и порты.
Page.js перехватывает переходы по ссылкам с помощью делегирования
событий на document. Чтобы игнорировать внешние ссылки,
необходимо добавить проверку внутри обработчика кликов:
document.addEventListener('click', function(event) {
const anchor = event.target.closest('a');
if (!anchor) return;
if (isExternalLink(anchor.href)) return; // Игнорируем внешние ссылки
event.preventDefault();
page(anchor.pathname);
});
Ключевой момент: метод closest('a') позволяет корректно
обрабатывать ссылки, вложенные в другие элементы, например кнопки или
картинки внутри <a>.
Page.js предоставляет возможность напрямую подключать фильтры перед вызовом маршрутов. Например, можно создать middleware для игнорирования внешних ссылок:
function ignoreExternal(ctx, next) {
if (isExternalLink(ctx.path)) return;
next();
}
page(ignoreExternal);
page('/about', () => {
console.log('Страница "О нас" загружена');
});
page('/contact', () => {
console.log('Страница "Контакты" загружена');
});
page();
Особенности работы:
ctx.path соответствует внешней ссылке, функция
прерывает цепочку, предотвращая вызов next().Часто внешние ссылки имеют атрибут target="_blank" или
класс .external. Page.js позволяет фильтровать их не только
по домену, но и по атрибутам:
document.addEventListener('click', function(event) {
const anchor = event.target.closest('a');
if (!anchor) return;
if (anchor.target === '_blank' || anchor.classList.contains('external')) return;
event.preventDefault();
page(anchor.pathname);
});
Такой подход позволяет разграничивать ссылки для внутренней навигации и ссылки, которые должны открываться в новом окне или на внешнем ресурсе.
Для надёжной фильтрации рекомендуется объединять проверку на внешнюю ссылку и проверку атрибутов:
function shouldHandleLink(anchor) {
return !isExternalLink(anchor.href) &&
anchor.target !== '_blank' &&
!anchor.hasAttribute('data-external');
}
document.addEventListener('click', function(event) {
const anchor = event.target.closest('a');
if (!anchor) return;
if (!shouldHandleLink(anchor)) return;
event.preventDefault();
page(anchor.pathname);
});
data-external позволяет явно маркировать
ссылки, которые Page.js игнорирует.Перехват кликов мышью — это не единственный способ навигации. Ссылки
могут активироваться клавишей Enter или через скрипты. Page.js
предоставляет объект page.start() с опцией
click: true/false для включения или отключения глобального
делегирования:
page.start({ click: true }); // Включает делегирование кликов
Чтобы полностью контролировать фильтрацию, можно отключить
автоматический перехват кликов и обрабатывать их вручную через событие
click, как показано выше.
<a> тегами.isExternalLink для всех ссылок. Избегается
дублирование логики.data-атрибуты.Такой подход позволяет Page.js корректно работать с внутренней навигацией, полностью игнорируя внешние ссылки, сохраняя гибкость, контроль и безопасность пользовательского интерфейса.