web components (2): custom elements

Los custom elements son otro de los pilares fundamentales de los web components

Franz Marc

archivado en: JavaScript / 29 diciembre, 2015 / taller:

Custom elements

En la entrada anterior de esta serie dedicada a los web components vimos en qué consistían los templates, en esta aprenderemos qué son los custom elements, esto es, etiquetas de html personalizadas.

Para hacernos una idea rápida de que consisten, valga el siguiente ejemplo en el que he creado un tag para incluir centauros en una página.

<!DOCTYPE html>

<html lang="es">

<head>

<meta charset="UTF-8">

<!-- Que no se nos olvide utilizar un polyfil para estos ejemplos -->

<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>

<title>Web Components</title>

</head>

<body>

<!-- nuestro componente centauro -->

<ce-centauro></ce-centauro>

<script>

var prototipoCentauro = Object.create(HTMLElement.prototype);

prototipoCentauro.createdCallback = function() {

this.textContent = "Soy un centauro que vigila los bosques";

}

document.registerElement("ce-centauro", {

prototype: prototipoCentauro

});

</script>

</body>

</html>

Y de esta forma tan sencilla podemos crear un tag centauro, fundamental en toda aplicación web digna de este nombre. Vamos a analizar ahora un poco este custom element.

Importante: El nombre de los custom elements debe incluir un guion, que es un carácter inexistente en los tags estándar.

Object.create()

Como he explicado varias veces en este blog, un objeto es un conjunto que agrupa métodos (funciones) y propiedades (variables).  En javaScript los objetos se pueden definir de tres maneras: mediante notación de literales, con una función constructora o con el método Object.create(), que ahora veremos con más detalle. Por cierto, te recomiendo esta serie sobre javaScript orientado a objetos si lo que estoy contando te suena a chino.

El segundo concepto que debemos tener claro antes de entrar en materia es el de prototipo, que podríamos definir como un objeto a partir del que se definen nuevos objetos. Por ejemplo, la clase Mamífero sería el prototipo de Gato, que a su vez sería el prototipo de mi gata Apache. Otro ejemplo: el prototipo de este array con los primeros números de la sucesión de Fibonacci...

var miArray = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34];

...es el objeto Array, del cual «hereda» todos sus métodos y propiedades, al igual que mi gatita he heredado la capacidad de arañar mi silla favorita de su prototipo Gato.

Pues bien, el método Object.create() puede recibir dos argumentos y el primero es precisamente su posible prototipo. En el ejemplo gatuno que estoy manejando:

var Gato = {

maullar: function() {

console.log("Miaaau!");

}

};

var miGata = Object.create(Gato);

miGata.maullar(); // Miaaau!

Volviendo a nuestro centauro, la primera línea queda ahora más clara:

var prototipoCentauro = Object.create(HTMLElement.prototype);

Lo que estamos haciendo ahí es definir un objeto mediante el método Object.create() a partir del prototipo de HTMLElement, que a su vez hereda los métodos y propiedades de Element. Es decir, hemos creado un objeto que hereda todas las características de un tag normal de html, como la capacidad de recibir eventos o ser draggable.

El ciclo de vida de un objeto

Al igual que los seres vivos pasamos por un ciclo -nacer, crecer, a veces reproducirse, y finalmente morir-, los objetos de javaScript pasan por diferentes estados desde que comienzan a vivir en DOM entre etiquetas, reglas de estilo, bugs y demás criaturas digitales que habitan en las páginas web. En total son cuatro estados, cuatro momentos, en los que podemos intervenir mediante funciones callback:

  • Cuando se crea (created), que tiene por función callback createdCallback.
  • Cuando se inserta (attached) en el DOM, momento que se puede capturar con el método attachedCallback.
  • Cuando se quita (detached) del DOM (detachedCallback).
  • Y cuando cambia algún atributo (attributeChangedCallback).

Teniendo esto en cuenta es fácil comprender las siguientes dos líneas de nuestro componente equino:

prototipoCentauro.createdCallback = function() {

this.textContent = "Soy un centauro que vigila los bosques";

}

Estamos diciendo que en el momento en que se cree el objeto, es decir, cuando el navegador «lea» un tag <ce-centauro></ce-centauro> (y puede haber varios en la misma página), el contenido de este objeto (this) sea el texto indicado.

Las dos últimas líneas del script carecen de misterio.

document.registerElement("ce-centauro", {

prototype: prototipoCentauro

});

Mediante el método registerElement() registramos nuestro nuevo elemento. Este método recibe dos parámetros: el primero con el nombre del tag, que recordemos debe llevar un guion entremedias; y el segundo un jasonako opcional con parámetros de configuración, como el posible prototipo del que se deriva el elemento.

Adenda: extender un elemento

En el caso del centauro estábamos creando un elemento desde cero, pero también podríamos haber partido de uno existente. Para eso, modificamos el prototipo cuando creamos el objeto especificando de cuál queremos partir como HTMLAudioElement, HTMLImageElement, HTMLParagraphElement, etcétera. Luego indicamos en las opciones del registerElement que vamos a extender ese elemento y, por último, en vez de incluir directamente el nuevo elemento, lo especificamos en el tag normal indicando que es (is) como el que hemos customizado. Por ejemplo, así crearíamos un nuevo tipo de input con el texto en rojo y en negrita.

<input is="in-input"></input>

<script>

var prototipoInputExtendido = Object.create(HTMLInputElement.prototype);

prototipoInputExtendido.createdCallback = function() {

this.style.fontWeight = "900";

this.style.color = "red";

}

document.registerElement("in-input", {

prototype: prototipoInputExtendido,

extends:'input'

});

</script>

|| Tags: ,

valoración de los lectores sobre web components (2): custom elements

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 5 sobre 5 (6 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.