API пользовательских атрибутов
Пользовательские элементы обычно наследуются от интерфейса HTMLElement, который представляет общий HTML-элемент. Есть возможность наследования от других, более конкретных элементов, используя несколько многословный синтаксис и атрибут is.
class ToggleButton extends HTMLButtonElement {
connectedCallback() {
// Логика
}
}
customElements.define(
'toggle-button',
ToggleButton,
{
extends: 'button'
}
);
Подробнее
Идея в том, чтобы расширять существующие элементы новым поведением, сохраняя семантику, доступность и встроенное поведение. В случае с кнопкой это фокусировка, активация с помощью клавиатуры, встроенная роль, отключение и так далее.
Этот API называется «Customized built-in elements» и давно поддерживается во всех браузерах, кроме Safari. Браузерные инженеры из Apple принципиально отказались реализовывать этот API, сославшись на целый ряд причин.
Если углубиться в детали, то причины вполне адекватные. Из-за отказа Apple от внедрения, Customized built-in elements практически не используются. Есть несколько альтернативных идей, которые учитывают обратную связь от Apple.
Одна из таких идей, Custom Attributes, обсуждалась на недавнем TPAC 2025. Есть несколько разных предложений, но основная суть в том, чтобы добавить API для создания пользовательских атрибутов по аналогии с пользовательскими элементами.
Атрибуты могут наследоваться от интерфейса Attr, который уже существует и представляет узел атрибута в DOM-дереве. У пользовательских атрибутов будут методы жизненного цикла для произвольной логики. В итоге получатся миксины для расширения элементов.
class ToggleElementAttr extends Attr {
// Встроенный тип данных
static dataType = AttributeType.IDREF;
// Опциональное значение по умолчанию
static defaultValue = null;
// Элемент, у которого установлен атрибут
ownerElement;
// Текущее значение атрибута
value;
// Атрибут подключен к элементу
connectedCallback() {
// Логика
}
// Атрибут удалён
disconnectedCallback() {}
// Атрибут изменился
changedCallback(oldValue, newValue) {}
}
HTMLButtonElement.attributeRegistry.define(
'toggle-element',
ToggleElementAttr
);
Подробнее
Это предложение также решает проблему HTML-first библиотек, таких как HTMX, Alpine.js, UIKit и других, которые используют нестандартные атрибуты для декларативного добавления логики и анализируют их с помощью регулярных выражений или XPath.
Custom Attributes API позволит убрать лишний код, который отвечает за поиск и разбор атрибутов и их значений. Работа с произвольными атрибутами должна стать удобнее и проще. Также пользовательские атрибуты будут считаться валидными.
// Где-то в коде htmx.js может быть так:
class HxPost extends Attr {
// ...
}
class HxSwap extends Attr {
// ...
}
const buttonAttrMap = {
'hx-post': HxPost,
'hx-swap': HxSwap,
// ...
}
for (const name in buttonAttrMap) {
HTMLButtonElement.attributeRegistry.define(
name,
buttonAttrMap[name]
);
}
Нажми меня
#html #js #web_api
Пользовательские элементы обычно наследуются от интерфейса HTMLElement, который представляет общий HTML-элемент. Есть возможность наследования от других, более конкретных элементов, используя несколько многословный синтаксис и атрибут is.
class ToggleButton extends HTMLButtonElement {
connectedCallback() {
// Логика
}
}
customElements.define(
'toggle-button',
ToggleButton,
{
extends: 'button'
}
);
Подробнее
Идея в том, чтобы расширять существующие элементы новым поведением, сохраняя семантику, доступность и встроенное поведение. В случае с кнопкой это фокусировка, активация с помощью клавиатуры, встроенная роль, отключение и так далее.
Этот API называется «Customized built-in elements» и давно поддерживается во всех браузерах, кроме Safari. Браузерные инженеры из Apple принципиально отказались реализовывать этот API, сославшись на целый ряд причин.
Если углубиться в детали, то причины вполне адекватные. Из-за отказа Apple от внедрения, Customized built-in elements практически не используются. Есть несколько альтернативных идей, которые учитывают обратную связь от Apple.
Дисклеймер: это обзор раннего предложения новых функций. Синтаксис может измениться в будущем или от функций могут отказаться.
Одна из таких идей, Custom Attributes, обсуждалась на недавнем TPAC 2025. Есть несколько разных предложений, но основная суть в том, чтобы добавить API для создания пользовательских атрибутов по аналогии с пользовательскими элементами.
Атрибуты могут наследоваться от интерфейса Attr, который уже существует и представляет узел атрибута в DOM-дереве. У пользовательских атрибутов будут методы жизненного цикла для произвольной логики. В итоге получатся миксины для расширения элементов.
class ToggleElementAttr extends Attr {
// Встроенный тип данных
static dataType = AttributeType.IDREF;
// Опциональное значение по умолчанию
static defaultValue = null;
// Элемент, у которого установлен атрибут
ownerElement;
// Текущее значение атрибута
value;
// Атрибут подключен к элементу
connectedCallback() {
// Логика
}
// Атрибут удалён
disconnectedCallback() {}
// Атрибут изменился
changedCallback(oldValue, newValue) {}
}
HTMLButtonElement.attributeRegistry.define(
'toggle-element',
ToggleElementAttr
);
Подробнее
Это предложение также решает проблему HTML-first библиотек, таких как HTMX, Alpine.js, UIKit и других, которые используют нестандартные атрибуты для декларативного добавления логики и анализируют их с помощью регулярных выражений или XPath.
Custom Attributes API позволит убрать лишний код, который отвечает за поиск и разбор атрибутов и их значений. Работа с произвольными атрибутами должна стать удобнее и проще. Также пользовательские атрибуты будут считаться валидными.
// Где-то в коде htmx.js может быть так:
class HxPost extends Attr {
// ...
}
class HxSwap extends Attr {
// ...
}
const buttonAttrMap = {
'hx-post': HxPost,
'hx-swap': HxSwap,
// ...
}
for (const name in buttonAttrMap) {
HTMLButtonElement.attributeRegistry.define(
name,
buttonAttrMap[name]
);
}
Нажми меня
#html #js #web_api