Existen ciertos elementos HTML como <dialog>
o elementos emergentes (con atributo popover
) que tradicionalmente no podían realizar ciertas acciones sin utilizar Javascript. Por ejemplo, las ventanas de diálogo no se podían abrir como ventanas modales sin utilizar Javascript, ya que había que llamar a la función showModal()
.
Para solucionar esto, aparece un nuevo mecanismo llamado Invocadores HTML (HTML Invokers). Es una estrategia que se basa en utilizar los atributos command
y commandfor
para invocar funciones o acciones concretas desde HTML, sin necesidad de hacer uso de Javascript.
Los atributos command
y commandfor
Mientras que en el atributo commandfor
se indica el id
del elemento que queremos controlar, mediante el atributo command
indicaremos uno de los siguientes valores:
Valor de command | Afecta a... | Descripción |
---|---|---|
show-modal | <dialog> | Muestra la ventana modal con el id indicado en commandfor . |
close | <dialog> | Cierra la ventana modal con el id indicado en commandfor . |
show-popover | <... popover> | Muestra el elemento con atributo popover y el id indicado en commandfor . |
hide-popover | <... popover> | Oculta el elemento con atributo popover y el id indicado en commandfor . |
toggle-popover | <... popover> | Combinación de las dos anteriores, mostrando u ocultando según la situación. |
Comando personalizado | <button> | Permite usar un comando personalizado. Aún experimental (ver más adelante). |
Como puedes ver, por el momento, tenemos tres enfoques diferentes: para ventanas de diálogo, para elementos emergentes y para comandos personalizados. Profundicemos un poco sobre ello.
Si conoces las ventanas de diálogo con <dialog>
, habrás visto que no permiten abrir ventanas modales sin utilizar Javascript. Sin embargo, con los invokers se puede conseguir:
- 1️⃣ Añadimos un
id
al elemento<dialog>
- 2️⃣ Añadimos a un
<button>
el atributocommandfor
indicando elid
del<dialog>
. - 3️⃣ Indicamos en el
<button>
el atributocommand
con uno de los valores:show-modal
oclose
.
Veamos un ejemplo en acción:
<button commandfor="modal" command="show-modal">Show modal</button>
<dialog id="modal">
Ejemplo de ventana de diálogo
<button commandfor="modal" command="close">Close</button>
</dialog>
Pulsando en los botones puedes abrir y cerrar la ventana de diálogo, sin hacer uso de Javascript. Recuerda que puedes usar el atributo HTML closedby
para elegir si el usuario puede cerrar la ventana pulsando fuera o presionando ESC.
Además de las ventanas de diálogo, los elementos emergentes (popovers) también permiten ser controlados mediante Invokers. El funcionamiento es muy similar al anterior:
- 1️⃣ Añadimos un
id
al elemento HTML con atributopopover
- 2️⃣ Añadimos a un
<button>
el atributocommandfor
indicando elid
del elemento anterior. - 3️⃣ Indicamos en el
<button>
el atributocommand
con uno de los valores:show-popover
,hide-popover
otoggle-popover
.
Veamos un ejemplo en acción:
<button commandfor="popover" command="show-popover">Show popover</button>
<button commandfor="popover" command="hide-popover">Hide popover</button>
<button commandfor="popover" command="toggle-popover">Toggle popover</button>
<div id="popover" popover open>
Ejemplo de popover
</div>
Como puedes ver, mediante el primer botón muestras el elemento, el segundo botón lo oculta, y el tercer botón permite alternar entre mostrar y ocultar. Recuerda que la característica principal de los elementos emergentes es que puedes pulsar fuera de ellos para cerrarlos.
Por último, y aún en fase experimental, podemos usar comandos personalizados en el atributo command
, indicándolos con el prefijo --
, seguido del nombre que queramos. Esta característica es muy probable que se amplie en el futuro, pero de momento sólo tiene definida esta funcionalidad.
En este ejemplo, hemos utilizado el comando --rotate-image
. El nombre lo hemos definido nosotros:
<button commandfor="image" command="--rotate-image">Rotate image</button>
<img id="image" src="https://manz.dev/manz-logo.png" alt="Image">
<style>
img {
width: 92px;
height: 92px;
}
</style>
const image = document.querySelector("#image");
let rotated = false;
image.addEventListener("command", ({ command, target }) => {
const isRotateCommand = command === "--rotate-image";
if (isRotateCommand) {
target.style.rotate = !rotated ? "-90deg" : "0deg";
rotated = !rotated;
}
});
Sin embargo, en este caso si tenemos que utilizar Javascript obligatoriamente. Utilizamos el evento command
para escuchar cuando se activa el comando, y podemos leer la propiedad command
para saber que comando se ha ejecutado por el usuario.
De esta forma se puede definir el comportamiento del comando personalizado.