hx-head
Объединяйте теги <head> с hx-head='merge'
Расширение hx-head позволяет ответам htmx обновлять <head> документа без полной перезагрузки страницы.
Установка
<script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/htmx.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/ext/hx-head.min.js"></script>
Использование
Добавление содержимого в head
Используйте hx-head="append", чтобы добавить стили, скрипты или метаданные, не удаляя текущее содержимое <head>:
<button hx-get="/dark-theme" hx-target="#preview"> Preview Dark Theme </button> <div id="preview">Light theme</div>
Сервер возвращает <head> и <body>:
<html> <head hx-head="append"> <link rel="stylesheet" href="/dark-theme.css"> </head> <body> Dark theme enabled </body> </html>
htmx добавляет таблицу стилей, а затем подменяет содержимое body в #preview:
<head>
<!-- Existing head content -->
<link rel="stylesheet" href="/dark-theme.css">
</head>
<body>
<button hx-get="/dark-theme" hx-target="#preview">
Preview Dark Theme
</button>
<div id="preview">Dark theme enabled</div>
</body> Замена содержимого head
Используйте hx-head="merge", если ответ представляет новую страницу:
<a hx-get="/settings" hx-target="body">Settings</a>
Текущая страница содержит:
<head> <title>Home</title> <link rel="stylesheet" href="/site.css"> <link rel="stylesheet" href="/home.css"> </head>
Сервер возвращает полный <head> для страницы настроек:
<html> <head hx-head="merge"> <title>Settings</title> <link rel="stylesheet" href="/site.css"> <link rel="stylesheet" href="/settings.css"> </head> <body> <h1>Settings</h1> </body> </html>
Слияние сохраняет точные совпадения, добавляет новые элементы и удаляет элементы, отсутствующие в ответе:
<head> <title>Settings</title> <link rel="stylesheet" href="/site.css"> <link rel="stylesheet" href="/settings.css"> </head> <body> <h1>Settings</h1> </body>
Сохранение существующего содержимого head
При слиянии удаляются текущие элементы, отсутствующие в ответе. Добавьте hx-preserve="true", чтобы сохранить элемент:
<head> <script src="/analytics.js" hx-preserve="true"></script> </head>
Скрипт останется, даже если в следующем ответе <head> он будет отсутствовать.
Атрибуты
hx-head
Укажите hx-head в <head> ответа, чтобы выбрать способ обновления head документа:
<head hx-head="<strategy>"> ... </head>
hx-head="merge"
Добавляет элементы из ответа и удаляет текущие элементы, отсутствующие в ответе:
<head hx-head="merge"> ... </head>
Новые элементы добавляются в конец текущего <head>.
hx-head="append"
Добавляет элементы из ответа, не удаляя текущие элементы:
<head hx-head="append"> ... </head>
Новые элементы добавляются в конец текущего <head>.
hx-head="re-eval"
Укажите hx-head="re-eval" у дочернего элемента <head>, чтобы заменить точное совпадение и выполнить его снова:
<head hx-head="merge">
<script hx-head="re-eval">
initializePage()
</script>
</head> Ответ должен содержать этот элемент каждый раз, когда его нужно выполнить.
Значения по умолчанию
В ответе можно не указывать hx-head. Стратегия выбирается в зависимости от целевого элемента запроса:
| Целевой элемент запроса | По умолчанию | Результат |
|---|---|---|
body |
merge |
Приводит текущее содержимое <head> в соответствие с ответом <head>
|
| Любой другой элемент | append |
Добавляет элементы из ответа, не удаляя текущие элементы |
События
Данные события доступны в event.detail.
События элемента содержат:
event.detail.headElement // Element being added or removed
htmx:head:before:merge
Вызывается перед обработкой расширением <head> ответа.
document.addEventListener('htmx:head:before:merge', event => {
if (!shouldUpdateHead(event.detail.ctx)) event.preventDefault()
}) Данные события включают ctx запроса. Отмените событие, чтобы пропустить всю обработку head для этого ответа.
htmx:head:before:add
Вызывается перед добавлением элемента head расширением.
document.addEventListener('htmx:head:before:add', event => {
if (event.detail.headElement.matches('script[data-untrusted]')) {
event.preventDefault()
}
}) Отмените событие, чтобы пропустить этот элемент.
htmx:head:before:remove
Вызывается перед удалением текущего элемента <head>.
document.addEventListener('htmx:head:before:remove', event => {
if (event.detail.headElement.matches('[data-keep]')) {
event.preventDefault()
}
}) Отмените событие, чтобы сохранить этот элемент.
htmx:head:after:merge
Вызывается после завершения обновления <head> расширением.
event.detail = {
added, // Added elements
kept, // Exact matches left in place
removed // Removed elements
} document.addEventListener('htmx:head:after:merge', event => {
console.log('Head elements added:', event.detail.added.length)
}) Миграция
От Beta к RC1
В RC1 события жизненного цикла hx-head имеют пространство имён:
| Beta | RC1 |
|---|---|
htmx:before:head:merge |
htmx:head:before:merge |
htmx:before:head:add |
htmx:head:before:add |
htmx:before:head:remove |
htmx:head:before:remove |
htmx:after:head:merge |
htmx:head:after:merge |
Примечания
-
Применяется
<style>, а<script>выполняется перед подменой;<script defer>выполняется после:<head hx-head="append"> <!-- Applies before swap --> <style>...</style> <!-- Runs before swap --> <script src="/app.js"></script> <!-- Runs after swap --> <script src="/after.js" defer></script> </head>
-
Ответы могут содержать теги
<head>без корневого элемента<html>:<!-- No <html> wrapper --> <head hx-head="append"> <meta name="theme-color" content="#000"> </head> <div>Saved</div>
Licensed under the Zero-Clause BSD License.
https://four.htmx.org/extensions/hx-head/