Custom Elements

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.

 

Note: Custom elements have only recently stabilized, and parts of MDN still contain documentation for outdated APIs from old specification drafts.

 

It may be unclear as to why the new custom elements capability was created, as it was already possible to create a tag name like <mytag> and style it with CSS, then use scripting to attach behaviors to it.  An advantage that custom elements have are their lifecycle reactions, which allow attaching behaviors to different parts of the new element's "lifecycle." For example, a certain behavior can be attached for when the element is inserted into the DOM ("connected"), and a different behavior when it is removed from the DOM ("disconnected"), or when its attributes change.

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

Custom elements have the following methods that govern how they behave:

constructor()
Called when the element is created or upgraded
connectedCallback()
Called when the element is inserted into a document, including into a shadow tree
disconnectedCallback()
Called when the element is removed from a document
attributeChangedCallback(attributeName, oldValue, newValue, namespace)
Called when an attribute is changed, appended, removed, or replaced on the element. Only called for observed attributes.
adoptedCallback(oldDocument, newDocument)
Called when the element is adopted into a new document

Ejemplo

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

HTML file:

If nothing appeared below, then your browser does not support Custom Elements yet.
<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>

JS file:

// 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';

    // Add the image to the shadow root.
    shadow.appendChild(img);

    // Add an event listener to the image.
    img.addEventListener('click', () => {
      window.location = this.getAttribute('data-url');
    });

    // Create a link to the product.
    var link = document.createElement('a');
    link.innerText = this.getAttribute('data-name');
    link.href = this.getAttribute('data-url');
    link.className = 'product-name';

    // Add the link to the shadow root.
    shadow.appendChild(link);
  }
}

// Define the new element
customElements.define('x-product', XProduct);

CSS file:

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;
}

Below is the live example of the above:

Observed attributes

To be notified when attributes change, a list of observed attributes must be defined when initializing the element, by placing an static observedAttributes getter on the element's class that returns an array of attribute names.

JS file:

class HelloElement extends HTMLElement {
  // Monitor the 'name' attribute for changes.
  static get observedAttributes() {return ['name']; }

  // Respond to attribute changes.
  attributeChangedCallback(attr, oldValue, newValue) {
    if (attr == 'name') {
      this.textContent = `Hello, ${newValue}`;
    }
  }
}

// Define the new element
customElements.define('hello-element', HelloElement);

HTML file:

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

Below is the live example of the above:

Specifications

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

Specification Status Comment
The HTML Standard: Custom elements LS  

Resources

Etiquetas y colaboradores del documento

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