Обратная совместимость

Unpoly — это библиотека для создания динамических пользовательских интерфейсов на основе существующих серверных страниц, которая делает акцент на плавную замену фрагментов страницы без полной перезагрузки. Одной из ключевых задач при работе с Unpoly является обеспечение обратной совместимости с классическим HTML и существующим JavaScript-кодом.

Обратная совместимость гарантирует, что даже при внедрении Unpoly старые ссылки, формы и скрипты продолжают работать, а новые возможности динамической подгрузки фрагментов не ломают существующую логику.


Работа с обычными ссылками и формами

Unpoly автоматически перехватывает клики по ссылкам и отправку форм, чтобы заменить часть страницы на серверный ответ. При этом сохраняется стандартное поведение для случаев, когда Unpoly не может обработать запрос:

<a href="/profile" up-target="#content">Профиль</a>
<form action="/update" method="post" up-target="#content">
  <input type="text" name="name">
  <button type="submit">Обновить</button>
</form>
  • Атрибут up-target указывает элемент, который будет обновлён.
  • Если up-target не указан, Unpoly заменяет <body> целиком, но при этом обычная загрузка страницы остаётся возможной.
  • Старые скрипты, ожидающие стандартное поведение формы, будут работать при добавлении атрибута up-keep к форме или ссылке.
<a href="/legacy" up-keep>Старая страница</a>

Ключевой момент: Unpoly не ломает существующие серверные эндпоинты. Сервер возвращает обычный HTML, и если Unpoly не активен, контент загружается стандартным образом.


Управление скриптами и событиями

При подгрузке фрагментов через Unpoly важно учитывать, что скрипты внутри загружаемых элементов не выполняются автоматически, если они подключены через <script> в HTML. Для обратной совместимости существуют следующие механизмы:

  1. События up:fragment:loaded и up:content:loaded — позволяют привязывать обработчики к вновь подгруженным элементам без изменения существующих функций.
up.on('up:fragment:loaded', function(event) {
  console.log('Фрагмент загружен:', event.target);
});
  1. Использование up.evaluateScripts — позволяет явно выполнить скрипты из подгруженного фрагмента:
up.fragment.load('/fragment', { target: '#container', evaluateScripts: true });
  1. Старые обработчики событий остаются в силе, если привязаны через addEventListener или jQuery. Unpoly не удаляет существующие элементы, а лишь заменяет их при необходимости.

Поддержка SEO и ссылок без JavaScript

Обратная совместимость включает поддержку пользователей без JS и поисковых систем:

  • Все ссылки и формы работают без Unpoly.
  • Атрибут up-href может использоваться для указания URL, к которому нужно обратиться при загрузке фрагмента, без изменения стандартного href.
<a href="/full-page" up-href="/partial">Частичная подгрузка</a>
  • Сервер должен возвращать полноценный HTML для стандартного запроса и фрагмент для AJAX-запроса (проверка через X-Up-Target в заголовках).

Работа с историями и навигацией

Unpoly интегрируется с History API, но при этом сохраняет обратную совместимость:

  • При переходе на новую страницу через Unpoly URL меняется, что позволяет использовать кнопку «Назад» браузера.
  • Старые ссылки без атрибутов up-target ведут себя как обычные переходы.
  • Для сохранения состояния элементов при навигации можно использовать up-history:
<a href="/page" up-target="#main" up-history>Перейти</a>
  • Если JavaScript отключен, ссылка всё равно работает как обычный переход.

Управление прогрессивным улучшением

Unpoly построен по принципу прогрессивного улучшения:

  • Страницы работают в обычном режиме без JS.
  • Добавление Unpoly не ломает серверный рендеринг.
  • Любые динамические элементы можно подключать постепенно, оставляя старый функционал доступным.

Примеры обратной совместимости:

  1. Формы с обычной отправкой POST и AJAX-подгрузкой.
  2. Ссылки, которые обновляют фрагменты и сохраняют URL.
  3. Скрипты и события, которые работают с элементами до и после подгрузки.

Работа с фрагментами и вложенными фрагментами

Unpoly позволяет работать с вложенными фрагментами, сохраняя старый код:

  • Вложенные фрагменты обновляются локально, без изменения всей страницы.
  • Существующие обработчики событий сохраняются, если элементы остаются в DOM.
  • Можно комбинировать up-target с up-keep для защиты определённых элементов от перерисовки.
<div id="sidebar" up-keep>
  <!-- Содержимое не будет заменяться -->
</div>

<div id="main" up-target>
  <!-- Загружаемый фрагмент -->
</div>

Работа с кешированием и загрузкой ресурсов

  • Unpoly поддерживает кеширование фрагментов через up-cache.
  • Старые страницы без Unpoly загружаются как обычно.
  • Кеширование не мешает работе существующих скриптов и стилей.
up.cache.set('/fragment', document.querySelector('#main').innerHTML);
  • Можно управлять временем жизни кеша и условиями обновления, сохраняя стабильное поведение старых страниц.

Итоговые рекомендации по совместимости

  • Всегда указывать up-target для динамических обновлений.
  • Использовать up-keep для элементов, которые не должны заменяться.
  • Привязывать события к документу через up.on для работы с подгружаемыми фрагментами.
  • Убедиться, что сервер корректно возвращает полный HTML для обычных запросов и фрагменты для AJAX.
  • Использовать прогрессивное улучшение как основной принцип внедрения Unpoly.

Эти правила позволяют плавно интегрировать Unpoly в существующие проекты без риска нарушить старый функционал и обеспечивают совместимость с любыми браузерами и пользовательскими сценариями.