Новое предложение от группы OpenUI - Invokers. Это декларативный способ привязать кнопку к какому-то элементу на странице и указать действие, которое будет вызвано при взаимодействии с этой кнопкой. На самом деле это довольно частая задача, чтобы при клике на кнопку с другим элементом что-то происходило. Примеров много: бургер-меню, модальное окно, выпадающее меню, переключение вкладки, смена слайда в галерее, отображение подсказки и т.д.
OpenUI предлагает добавить кнопкам (
<button>, <input type="button"> и <input type="reset">) два новых атрибута:1)
invokertarget - цель действия, принимает id элемента, с которым что-то должно произойти.2)
invokeraction - название действия, которое необходимо выполнить.<button invokertarget="my-video" invokeraction="playpause">Play/Pause</button>
<button invokertarget="my-video" invokeraction="toggleMuted">Mute/Unmute</button>
<video id="my-video" src="video.mp4"></video>
invokeraction можно не указывать, тогда подразумевается значение auto, при котором вызываются стандартные действия в зависимости от элемента. Для <dialog> и [popover] это будет открытие или закрытие, для <audio> и <video> - пауза и воспроизведение.<button invokertarget="my-dialog">This opens a dialog</button>
<dialog id="my-dialog">This is the dialog</dialog>
Также можно указать действие в виде ключевого слова, которое будет соответствовать (скорее всего) названию метода элемента. Например, кнопке-крестику внутри
<dialog> можно указать invokeraction="close", что будет вызывать метод close() у <dialog>.<button invokertarget="my-dialog">Open dialog</button>
<dialog id="my-dialog">This is the dialog
Hello world!
<button invokertarget="my-dialog" invokeraction="close">Close</button>
</dialog>
А что, если метода нет? Тогда ничего не произойдёт. Но можно подписаться на событие
invoke, в обработчике которого можно прочитать действие из invokeraction и предпринять какие-то действия с элементом. Это также может быть хорошей альтернативой для делегирования событий.<button invoketarget="my-custom">Invoke a div... to do something?</button>
<button invoketarget="my-custom" invokeaction="frobulate">Frobulate</button>
<div id="my-custom"></div>
<script>
document.getElementById("my-custom").addEventListener("invoke", (e) => {
if (e.action === "auto") {
console.log("invoked an auto action!");
} else if (e.action === "frobulate") {
alert("Successfully frobulated the div");
}
});
</script>
Событие вызывается при клике мышкой, нажатии клавиш
Enter или Space, касании пальцем на тач-устройствах. А если хочется не по нажатию, а по наведению? Для этого предусмотрены атрибуты interesttarget и interestaction. Работают так же, как и invoker*, но только по ховеру.<button interesttarget="my-popover">Open Popover</button>
<div id="my-popover" popover="hint">Hello world</div>
Для консистентности эти атрибуты в скором времени должны заменить атрибуты из Popover API, такие как
popovertarget и popoveraction, поскольку они повторяют логику invoker* и interest*. Какое-то время будут работать оба, после чего popover* объявят deprecated. С точки зрения accessibility, у кнопки с этими атрибутами будет неявно установлены соответствующие aria-атрибуты:
aria-controls, aria-details и aria-expanded в зависимости от типа целевого элемента.Более подробно и с примерами можно ознакомиться в черновике предложения OpenUI. Когда этого ждать? Chrome и Firefox уже взяли это в работу, со временем остальные браузеры должны подтянуться.