Руководство по созданию расширений htmx
Система расширений htmx 4, хуки событий и внутренний API.
В htmx 4 появилась система расширений, основанная на хуках событий, а не на старом API на основе обратных вызовов.
Определение расширения
Расширения определяются с помощью htmx.registerExtension():
htmx.registerExtension("my-ext", {
init: (internalAPI) => {
// Called once when extension is registered
// Store internalAPI reference if needed
},
htmx_before_request: (elt, detail) => {
// Called before each request
// Return false to cancel
},
htmx_after_request: (elt, detail) => {
// Called after each request
},
}); Хуки событий
Расширения подключаются к событиям жизненного цикла htmx. В именах событий используются символы подчёркивания вместо двоеточий:
Основные события жизненного цикла
| Имя хука | Вызываемое событие | Параметры | Описание |
|---|---|---|---|
htmx_before_init |
htmx:before:init |
(elt, detail) |
Перед инициализацией элемента |
htmx_after_init |
htmx:after:init |
(elt, detail) |
После инициализации элемента |
htmx_before_process |
htmx:before:process |
(elt, detail) |
Перед обработкой элемента |
htmx_after_process |
htmx:after:process |
(elt, detail) |
После обработки элемента |
htmx_before_cleanup |
htmx:before:cleanup |
(elt, detail) |
Перед очисткой элемента |
htmx_after_cleanup |
htmx:after:cleanup |
(elt, detail) |
После очистки элемента |
События жизненного цикла запроса
| Имя хука | Вызываемое событие | Параметры | Описание |
|---|---|---|---|
htmx_config_request |
htmx:config:request |
(elt, detail) |
Настройка запроса перед отправкой |
htmx_before_request |
htmx:before:request |
(elt, detail) |
Перед отправкой запроса |
htmx_before_response |
htmx:before:response |
(elt, detail) |
После получения ответа, до обработки тела |
htmx_after_request |
htmx:after:request |
(elt, detail) |
После завершения запроса |
htmx_finally_request |
htmx:finally:request |
(elt, detail) |
При завершении, сбое или отмене запроса |
htmx_error |
htmx:error |
(elt, detail) |
При ошибке запроса |
События замены содержимого
| Имя хука | Вызываемое событие | Параметры | Описание |
|---|---|---|---|
htmx_before_swap |
htmx:before:swap |
(elt, detail) |
Перед заменой содержимого |
htmx_after_swap |
htmx:after:swap |
(elt, detail) |
После замены содержимого |
htmx_finally_swap |
htmx:finally:swap |
(elt, detail) |
После замены (при успехе или ошибке) |
htmx_before_settle |
htmx:before:settle |
(elt, detail) |
Перед этапом стабилизации |
htmx_after_settle |
htmx:after:settle |
(elt, detail) |
После этапа стабилизации |
handle_swap |
(прямой вызов) | (swapStyle, target, fragment, swapSpec) |
Обработчик пользовательской замены |
События истории
| Имя хука | Вызываемое событие | Параметры | Описание |
|---|---|---|---|
htmx_before_history_update |
htmx:before:history:update |
(elt, detail) |
Перед обновлением истории |
htmx_after_history_update |
htmx:after:history:update |
(elt, detail) |
После обновления истории |
htmx_after_history_push |
htmx:after:history:push |
(elt, detail) |
После добавления записи в историю |
htmx_after_history_replace |
htmx:after:history:replace |
(elt, detail) |
После замены записи в истории |
htmx_before_history_restore |
htmx:before:history:restore |
(elt, detail) |
Перед восстановлением из истории |
Отмена событий
Чтобы отменить событие, верните false или задайте detail.cancelled = true:
htmx.registerExtension("validator", {
htmx_before_request: (elt, detail) => {
if (!isValid(detail.ctx)) {
return false; // Cancel request
}
},
}); Внутренний API
Хук init получает объект внутреннего API со вспомогательными методами:
let api;
htmx.registerExtension("my-ext", {
init: (internalAPI) => {
api = internalAPI;
},
htmx_after_init: (elt) => {
let value = api.attributeValue(elt, "hx-my-attr");
let specs = api.parseTriggerSpecs("click, keyup delay:500ms");
let { method, action } = api.determineMethodAndAction(elt, evt);
},
}); Доступные методы внутреннего API:
-
HCON— разбор и объединение значений HCON -
attributeValue(elt, name, defaultVal, returnElt)— получение значения атрибута с поддержкой наследования -
parseTriggerSpecs(spec)— разбор спецификации триггера -
determineMethodAndAction(elt, evt)— получение{method, action}элемента -
createRequestContext(elt, evt)— создание контекста запроса -
collectFormData(elt, form, submitter, validate, isGet)— сбор данных формы -
getAttributeObject(elt, name, callback, scope)— чтение атрибута со значением-объектом -
insertContent(task, cssTransition)— вставка содержимого задачи замены -
morph(oldNode, fragment, innerHTML)— морфинг существующего содержимого -
isSoftMatch(oldNode, newNode)— проверка возможности морфинга двух узлов -
initSecurity(ttPolicy, syncFn, asyncFn)— настройка Trusted Types и конструкторов скриптов -
onTrigger(elt, spec, handler)— подключение обработчика разобранного триггера -
htmxProp(elt)— получение внутреннего состояния htmx элемента -
triggerHtmxEvent(elt, name, detail, bubbles)— отправка события htmx -
executeJavaScript(thisArg, values, code, expression, isAsync)— выполнение JavaScript в соответствии с политикой безопасности htmx
Контекст запроса
Объект detail.ctx содержит информацию о запросе:
{
sourceElement, // Element triggering request
sourceEvent, // Event that triggered request
status, // Request status
target, // Target element for swap
swap, // Swap strategy
request: {
action, // Request URL
method, // HTTP method
headers, // Request headers
body, // FormData during htmx_config_request; final BodyInit later
validate, // Whether to validate
abort, // Function to abort request
signal // AbortSignal
},
response: { // Available after request
raw, // Raw Response object
status, // HTTP status code
headers // Response headers: https://developer.mozilla.org/en-US/docs/Web/API/Headers
},
text, // Response text (after request)
hx // HX-* response headers (parsed)
} Пользовательские стратегии замены
Расширения могут реализовывать пользовательские стратегии замены:
htmx.registerExtension("my-swap", {
handle_swap: (swapStyle, target, fragment, swapSpec) => {
if (swapStyle === "my-custom-swap") {
target.appendChild(fragment);
return true; // Handled
}
return false; // Not handled
},
}); Информацию о переносе расширений, написанных для htmx 2.x, см. в разделе Перенос расширений на htmx 4.
Licensed under the Zero-Clause BSD License.
https://four.htmx.org/docs/extension-authoring-guide/