Unpoly — это библиотека для прогрессивного улучшения веб-приложений, позволяющая обновлять только части страницы без полной перезагрузки. Ключевая концепция — частичный рендер (partial rendering), при котором сервер возвращает HTML-фрагмент, который заменяет или дополняет существующую разметку на клиенте. Это ускоряет интерфейс, снижает нагрузку на сервер и обеспечивает плавный пользовательский опыт.
В Unpoly обновление происходит по селекторам, задающим контейнеры, которые будут заменены. Например:
<div id="content">
<p>Старое содержимое</p>
</div>
<a href="/new_content" up-target="#content">Обновить</a>
up-target — атрибут, указывающий,
какой элемент DOM будет обновлён.up-target не задан, Unpoly пытается определить
контейнер автоматически по совпадению селектора
<body> или <main>.Важно: селекторы должны быть уникальными и точными, чтобы избежать случайного обновления лишних частей страницы.
Unpoly поддерживает несколько способов вставки новых фрагментов:
replace (по умолчанию) — заменяет
существующий контейнер полностью.
insert — добавляет контент внутрь
контейнера:
up-insert="before" — вставляет перед контейнером.up-insert="after" — вставляет после контейнера.up-insert="top" — вставляет в начало контейнера.up-insert="bottom" — вставляет в конец контейнера.remove — удаляет контейнер после
успешного ответа сервера.
Пример вставки в конец списка:
<ul id="messages">
</ul>
<a href="/new_message" up-target="#messages" up-insert="bottom">Добавить сообщение</a>
Сервер может возвращать:
<div id="content">...</div>. Unpoly заменяет
контейнер полностью.<p>Новый текст</p>. Тогда контейнер, указанный
в up-target, остаётся, а фрагмент вставляется внутрь
согласно стратегии up-insert.Для корректной работы важно, чтобы сервер возвращал HTML, валидный и семантически согласованный с текущей структурой DOM.
Помимо up-target и up-insert есть другие
важные атрибуты:
up-transition — задаёт анимацию
замены содержимого:
<div id="content" up-transition="fade">...</div>
Поддерживаются эффекты: fade, slide,
cross-fade, а также кастомные CSS-классы.
up-swap — определяет, как именно
вставляется новый контент (replace, after,
before, prepend,
append).
up-on-success /
up-on-error — позволяют выполнять JS-функции после
успешного или неудачного рендера.
up-confirm — выводит диалог
подтверждения перед запросом:
<a href="/delete_item" up-target="#item" up-confirm="Вы уверены?">Удалить</a>Unpoly поддерживает множественные частичные обновления одновременно:
<a href="/update" up-target="#content1,#content2">Обновить оба блока</a>
Все указанные селекторы будут обновлены одной серверной отдачей.
Сервер может возвращать несколько контейнеров одновременно:
<div id="content1">...</div>
<div id="content2">...</div>Вложенные обновления особенно полезны при работе с формами и списками, где изменение одной части интерфейса требует синхронизации других блоков.
Формы в Unpoly обрабатываются с поддержкой AJAX по умолчанию:
<form action="/update_form" method="post" up-target="#form-container">
<input type="text" name="name">
<button type="submit">Сохранить</button>
</form>
#form-container.up-validate="true" для
автоматической валидации и отображения ошибок без перезагрузки.Также формы поддерживают замену кнопок и полей по
селекторам через атрибут up-target на отдельных
элементах формы.
Unpoly предоставляет JS-API для динамического частичного рендеринга:
up.replace('#content', '/new_content');
up.append('#messages', '<li>Новое сообщение</li>');
Основные методы:
up.replace(target, urlOrHtml) —
заменяет контейнер.up.append(target, content) /
up.prepend(target, content) — добавляет
контент.up.remove(target) — удаляет
элементы.up.insertAfter(target, content) /
up.insertBefore(target, content) — вставляет рядом
с контейнером.Методы позволяют гибко интегрировать Unpoly с динамическими компонентами и сторонними библиотеками.
Unpoly автоматически обновляет историю браузера при частичных рендерах:
Атрибут up-history="false" отключает запись:
<a href="/new_content" up-target="#content" up-history="false">Обновить без истории</a>Можно задавать заголовок страницы через
up-title:
<div up-title="Новый заголовок">...</div>История корректно работает с кнопками «Назад» и «Вперёд», повторно вызывая частичные рендеры без перезагрузки страницы.
Частичные рендеры могут не сработать из-за:
up-target.Для отладки полезны встроенные события Unpoly:
document.addEventListener('up:fragment:loaded', event => {
console.log('Фрагмент загружен:', event.target);
});
up:fragment:loaded — вызывается после
вставки нового контента.up:fragment:loading — перед отправкой
запроса.up:fragment:failed — при ошибке
сервера.up-target, избегая селекторов по тегам.up-validate и
up-on-success для удобного UX.up-transition делают интерфейс плавным,
но не должны блокировать пользовательские действия.replace,
append и вложенных рендеров для максимальной
динамичности.Частичные рендеры в Unpoly позволяют создавать интерактивные веб-приложения с минимальной нагрузкой и плавным пользовательским опытом, комбинируя простые HTML-фрагменты, селекторы и JS-API.