MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/d6d7ff2e2f9c

Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

Los Custom Elements son una característica que permite crear tus propios elementos HTML personalizados. Pueden tener un comportamiento personalizado y estilos CSS propios. Son una parte de los Web Components, pero también pueden ser utilizados independientemente.

Nota: Los Custom elements sólo se han estabilizado recientemente, y partes de MDN todavía contienen información desactualizada de las APIs de los antiguos borradores de la especificación.

Puede no estar claro por qué se creó la nueva capacidad de elementos personalizados, ya que ya era posible crear una etiqueta como <mytag> y aplicarle estilo con CSS, luego utilizar scripts para darle comportamiento. Una ventaja que tienen los custom elements son las reacciones de ciclo de vida (lifecycle reactions), que permiten asociar comportamiento a diferentes partes del nuevo "ciclo de vida" del elemento. Por ejemplo, se puede asociar un comportamiento concreto cuando un nuevo elemento se inserta en el DOM ("conectado"), y otro distinto cuando es eliminado del DOM ("desconectado"), o cuando sus atributos cambien.

The key enabler of v1 custom elements is the CustomElementRegistry.define() method, which can be used to define a new custom element. The new element will then use the supplied class for any instances, instead of the default HTMLUnknownElement. Custom elements can also be based on a native element like <button>, by using the syntax <button is="my-button">; these are called customized built-in elements.

Métodos de custom element

Los Custom elements tienen los siguientes métodos que dictan su comportamiento:

constructor()
Llamado cuando el elemento es creado o actualizado
connectedCallback()
Llamado cuando el elemento se es insertado en el documento, incluyéndose en un árbol shadow
disconnectedCallback()
Llamado cuando el elemento es eliminado de un documento
attributeChangedCallback(nombreDelAtributo, antiguoValor, nuevoValor, dominio)
Llamado cuando un atributo es cambiado, concatenado, eliminado o reemplazado en el elemento. Sólo llamado sobre atributos observados.
adoptedCallback(antiguoDocumento, nuevoDocumento)
Llamado cuando un elemento es adoptado en otro nuevo documento

Ejemplo

Los custom elements necesitan usar la sintaxis de clase introducida en las versiones modernas de JavaScript.

Archivo HTML:

Si no aparece nada debajo, es que tu navegador no soporta aún los Custom Elements.
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>

Archivo JS:

// Declaración de un custom element que hereda de HTMLElement
class XProduct extends HTMLElement {
  constructor() {
    // Siempre debe llamarse primero al constructor padre
    super();

    // Se crea el shadow root
    var shadow = this.attachShadow({mode: 'open'});

    // Se crea un elemnto img y se asignan sus atributos.
    var img = document.createElement('img');
    img.alt = this.getAttribute('data-name');
    img.src = this.getAttribute('data-img');
    img.width = '150';
    img.height = '150';
    img.className = 'product-img';

    // Añadir la imagen al shadow root.
    shadow.appendChild(img);

    // Añadir un elemento de escucha a la imagen.
    img.addEventListener('click', () => {
      window.location = this.getAttribute('data-url');
    });

    // Crear un enlace al producto.
    var link = document.createElement('a');
    link.innerText = this.getAttribute('data-name');
    link.href = this.getAttribute('data-url');
    link.className = 'product-name';

    // Añadir el enlace al shadow root.
    shadow.appendChild(link);
  }
}

// Definir el nuevo elemento.
customElements.define('x-product', XProduct);

Archivo CSS:

body {
  background: #F7F7F7;
}

x-product {
  display: inline-block;
  float: left;
  margin: 0.5em;
  border-radius: 3px;
  background: #FFF;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  font-family: Helvetica, arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

x-product::slotted(.product-img) {
  cursor: pointer;
  background: #FFF;
  margin: 0.5em;
}

x-product::slotted(.product-name) {
  display: block;
  text-align: center;
  text-decoration: none;
  color: #08C;
  border-top: 1px solid #EEE;
  font-weight: bold;
  padding: 0.75em 0;
}

A continuación se muestra el ejemplo en vivo de lo anterior:

Atributos Observados

Para ser notificado cuando un atributo cambia, se debe definir una lista de atributos observados al inicializar el elemento, poniendo un getter estático observedAttributes en la clase del elemento que devuelve un array de nombre de atributos.

Archivo JS:

class HelloElement extends HTMLElement {
  // Observar los cambios en el atributo 'name'.
  static get observedAttributes() {return ['name']; }

  // Responder a los cambios en el atributo.
  attributeChangedCallback(attr, oldValue, newValue) {
    if (attr == 'name') {
      this.textContent = `Hello, ${newValue}`;
    }
  }
}

// Definir el nuevo elemento
customElements.define('hello-element', HelloElement);

Archivo HTML:

<hello-element name="Anita"></hello-element>

A continuación está el ejemplo en vivo de lo anterior:

Especificaciones

Los Custom Elements están definido en la siguiente especificación:

Especificación Estado Comentario
The HTML Standard: Custom elements LS  

Recursos

Etiquetas y colaboradores del documento

 Colaboradores en esta página: AlePerez92, fipadron, V.Morantes
 Última actualización por: AlePerez92,