К содержанию

Навигация

Навигация по областям страницы

В рабочем интерфейсе вокруг содержимого стоит оболочка: меню, профиль, шапка. При переходе по ссылке внутри оболочки достаточно заменить одну область — содержимое, а оболочку оставить на месте. Это делает SF.RegionNavigation из ядра Framework: объект доступен сразу после выполнения core.js, но ничего не делает, пока страница его не включит. Ответ области готовит сервер продукта; Framework описывает только контракт.

Включение

Страница включает навигацию один раз, назвав область, её место на странице, заголовок запроса и метку ревизии оболочки:

HTML
<meta name="shop-shell-revision" content="2026-10-16.3">

<header>…меню и профиль…</header>
<main id="shop-content">
  <h1>Заказы</h1>
  …
</main>

<script>
  SF.RegionNavigation.enable({
    region: 'content',
    root: '#shop-content',
    header: 'X-Shop-Region',
    revisionMeta: 'shop-shell-revision',
    scope: '/admin'
  });
</script>
Настройка Что задаёт По умолчанию
region имя области, которую просит навигация; сервер возвращает его в ответе content
root селектор или сам элемент области на странице обязательна
header имя заголовка запроса, которым страница просит область; значение заголовка — имя области обязательна
revisionMeta имя <meta>, в content которого лежит ревизия оболочки обязательна
scope начало пути: навигация берёт только адреса, путь которых с него начинается /
onFullLoad функция (url, reason), которая вызывается вместо полной загрузки страницы —

Без root, header или revisionMeta вызов выбрасывает TypeError. Повторный enable() заменяет прежние настройки. Имя заголовка и метки выбирает продукт; Framework не знает имён продуктов.

Какие ссылки берёт навигация

Навигация берёт обычный щелчок левой кнопкой по a[href] без клавиш Ctrl, Cmd, Shift и Alt, если адрес:

  • на том же источнике, что страница;
  • лежит под scope;
  • не ведёт к якорю на этой же странице.

Браузеру остаются ссылки с download, ссылки с target, отличным от _self, ссылки внутри элемента с атрибутом data-full-load и щелчки, которые уже обработал другой код (preventDefault()).

HTML
<a href="/admin/orders">Заказы</a>            <!-- меняется область -->
<a href="/admin/reports" data-full-load>Отчёты</a> <!-- загружается вся страница -->

Запрос и ответ сервера

Навигация отправляет GET по адресу ссылки с куками этого сайта и двумя заголовками: заголовком из header со значением region и Accept: application/json. Сервер отвечает статусом 200 и JSON с типом application/json:

JSON
{
  "region": "content",
  "html": "<h1>Заказы</h1><shop-order-list></shop-order-list>",
  "title": "Заказы — Магазин",
  "assets": [
    {"key": "shop.orders", "href": "/assets/orders.css", "kind": "css"},
    {"key": "shop.orders", "href": "/assets/orders.js", "kind": "javascript"}
  ],
  "shell_revision": "2026-10-16.3",
  "url": "/admin/orders?status=new"
}
Поле Что означает
region имя области; должно совпасть с region из настроек
html разметка области, строкой
title заголовок документа после перехода; необязательно
assets ресурсы области: href, kind (css или javascript) и необязательный key, который попадает в атрибут data-sf-asset; необязательно
shell_revision ревизия оболочки, строкой; должна совпасть с ревизией в <meta> страницы
url адрес, который попадает в историю; если его нет или он на другом источнике, в историю попадает адрес ссылки

Без заголовка области тот же адрес отдаёт обычную HTML-страницу. Ответы HTML и JSON живут по одному адресу, поэтому сервер ставит Vary с именем заголовка области, чтобы кеш их не смешал. Перенаправление на вход остаётся перенаправлением: навигация увидит его и загрузит страницу целиком.

Когда страница загружается целиком

Навигация никогда не оставляет на экране наполовину заменённую страницу. Страница загружается целиком, если:

  • ревизия оболочки в ответе отличается от ревизии на странице — значит, изменилась сама оболочка;
  • статус ответа не 200, ответ пришёл через перенаправление или его тип не application/json;
  • в ответе другая область, html не строка, нет shell_revision или assets не список;
  • ответ не пришёл за 15 секунд или запрос завершился сбоем;
  • на странице нет элемента области или <meta> с ревизией.

Перед полной загрузкой на document приходит событие sf-region-fallback с detail: {url, reason}. Если задан onFullLoad, вызывается он, и страница остаётся на месте.

Что происходит при переходе

  1. На document приходит отменяемое событие sf-region-navigate с detail: {url, region}. preventDefault() отменяет переход.
  2. Незавершённый прежний запрос прерывается; применяется только последний.
  3. Если ответ задерживается дольше 150 мс, область получает aria-busy и скелетон data-sf-region-loading; оболочка не меняется (Скелетон области страницы).
  4. Таблицы стилей области загружаются до замены, поэтому новое содержимое не показывается без оформления.
  5. Адрес попадает в историю, содержимое области заменяется — в переходе View Transitions, если браузер его поддерживает и человек не просил уменьшить движение. Элементы, которые ушли, отключаются и освобождают свои маршруты, слушатели и таймеры. Заголовок документа берётся из title.
  6. Скрипты области загружаются после замены, и её элементы оживают на месте.
  7. Прокрутка уходит в начало, фокус — на первый h1 области (он получает tabindex="-1", если своего нет).
  8. На document приходит событие sf-region-load с detail: {url, region, title}.

Ресурсы загружаются один раз

Ресурсы области — это assets из ответа и теги <link rel="stylesheet"> и <script src> внутри html. Навигация вынимает их из разметки и загружает сама: каждый адрес один раз за жизнь страницы. Ресурс, который уже подключён на странице, повторно не запрашивается; две области с одним файлом ждут один и тот же запрос. Встроенный <script> без src из разметки области удаляется и не выполняется: код области приходит файлами.

Если файл не загрузился, область всё равно показывается, а компонент, которому файл был нужен, сам сообщает своё состояние.

«Назад» и «Вперёд»

Каждая запись истории, в том числе та, с которой страница открылась, помечена навигацией. «Назад» и «Вперёд» снова просят область по адресу записи и заменяют её тем же путём; «Назад» возвращает прокрутку, которая была у записи. Навигация берёт восстановление прокрутки на себя (history.scrollRestoration = 'manual').

Управление из кода

Член Что делает
enable(options) включает навигацию; возвращает true
navigate(url) переходит по адресу так же, как по ссылке; возвращает обещание true, если область заменена, и false, если переход отменён или страница загружается целиком. Без включённой навигации просто открывает адрес
disable() снимает обработчики щелчков и истории и прерывает незавершённый запрос
enabled true, пока навигация включена
Событие detail Когда
sf-region-navigate {url, region} перед запросом; отменяемое
sf-region-load {url, region, title} область заменена, скрипты загружены, фокус на заголовке
sf-region-fallback {url, reason} перед полной загрузкой страницы

Все три события приходят на document.

Смотрите также

Поиск по документации

Введите минимум 2 символа

    Настройки

    Тема
    Размер шрифта
    Ширина страницы