Los Custom Elements del estándar Javascript de Web Components permiten extender el HTML de manera nativa, creando unidades o etiquetas que encapsulan un aspecto y una funcionalidad. En este artículo te explicaremos cómo construir uno de ellos, demostrando lo fácil que es sacar partido a las ventajas del estándar, usando únicamente Javascript.
¿Por qué son importantes los Web Components?
En el mundo de la web nos mueven los estándares, lenguajes como HTML, CSS o Javascript. Mucha gente no sabe que algunas de las herramientas que usa en el día a día se pueden sustituir por un estándar. El estándar Web Components nos permite hacer muchas de las cosas que hacen librerías como jQuery, React, Angular… pero sin necesidad de recargar al navegador con pesados scripts que hay que descargar y procesar, consumiendo tiempo, rendimiento y batería de los dispositivos. Hoy todos los navegadores actuales son compatibles con Web Components, así que no hay un motivo para no usarlos.
Definición de un custom element (componente)
La definición de un componente, o elemento personalizado, se realiza mediante una clase (de programación orientada a objetos) de código Javascript. Para ello simplemente tenemos que extender la clase del elemento HTML genérico, llamado HTMLElement.
Luego usamos una instrucción del estándar de Web Components para registrar esa clase como implementación del elemento personalizado, indicando el nombre de una nueva etiqueta que queremos crear. Con el único detalle que ese nombre necesita llevar en medio el siguiente caracter «-«.
class FechaHoy extends HTMLElement { // Definición del componente } window.customElements.define('fecha-hoy', FechaHoy);
Como puedes ver, el método usado para registrar un elemento personalizado se llama customElements.define(). Como primer parámetro le indicamos el nombre de la etiqueta y como segundo parámetro indicamos la clase que lo implementa.
Gracias al código anterior, ahora el navegador entenderá la etiqueta <fecha-hoy> y le asignará el mismo comportamiento que un elemento del HTML genérico, el que podría tener la etiqueta <div>.
Personalizar el componente
Ahora veamos cómo aplicar un poco de contenido al componente. En nuestro caso queremos conseguir que el elemento muestre la fecha de hoy cuando se visualice en la página.
El mecanismo más potente para conseguir agregar marcado al componente que acabamos de crear es la generación de «Shadow DOM». Esto es un poco de lenguaje HTML que se puede agregar al componente y que permanecerá encapsulado, sin que otros elementos de la página puedan producir interferencias en él de manera accidental.
Para ello vamos a crear en el constructor el Shadow DOM con el método attachShadow() y agregarle algo de contenido con la conocida propiedad del DOM innerHTML.
class FechaHoy extends HTMLElement { constructor() { super(); let shadowRoot = this.attachShadow({mode: 'open'}); shadowRoot.innerHTML = `<div>${this.fecha()}</div>`; } fecha() { var today = new Date(); var dia = String(today.getDate()); var mes = String(today.getMonth() + 1); //January is 0! var ano = today.getFullYear(); return `${dia}/${mes}/${ano}`; } } window.customElements.define('fecha-hoy', FechaHoy);
Ahora nuestra clase tiene dos métodos, el constructor, que se encargará de crear el marcado encapsulado en el elemento, y una pequeña función que se ocupará de la funcionalidad de obtener la fecha del día actual. Si quisiéramos, podríamos incluso agregar algo de estilos CSS al componente, simplemente colocando una etiqueta <style> dentro del marcado agregado al nodo de shadow DOM. Nos quedaría así:
shadowRoot.innerHTML = ` <style> div { font-size: 0.8em; color: blue; } </style> <div>${this.fecha()}</div>`;
Una vez incluido el script Javascript que define el componente (la clase de implementación que acabamos de realizar y el método de definición del componente «customElements.define»), podemos usar el nuevo elemento que acabamos de crear, como si fuera cualquier otra etiqueta HTML conocida.
<fecha-hoy></fecha-hoy>
El componente entonces lucirá de esta manera:
Conclusión
Como puedes ver, hemos usado código Javascript nativo para todo. No hemos incorporado ninguna librería adicional, por lo que este componente no representará ningún esfuerzo extra para el navegador que visite nuestra página, ni a la hora de descargar el contenido ni a la hora de procesarlo.
Además, nos estamos asegurando que la vida del componente sea lo más larga posible, ya que no dependemos de librerías de terceros, que requerirán actualizaciones o migraciones cuando dejen de estar soportadas. Por supuesto, este componente estándar es compatible, no solo con la variedad de navegadores existentes actualmente, sino también con el uso de cualquier librería que se use actualmente en el proyecto, ya que es solamente Javascript nativo. Sólo hemos visto el principio de todo lo que Web Components te puede ofrecer. No dejes de investigar cómo adoptar esta tecnología.