CustomElementRegistry.define()

This translation is incomplete. Please help translate this article from English

El método define() de la interfaz CustomElementRegistry define un nuevo elemento personalizado.

Se pueden crear dos tipos de elementos personalizados:

  • Elementos personalizados autónomos: Elementos autónomos; estos heredan de HTMLElement  (Elemento HTML genérico).
  • Elementos personalizados preconstruidos: Estos elementos heredan - y extienden - elementos HTML ya existentes (p.ej HTMLParagraphElement que es el elemento HTML <p>).

Sintaxis

customElements.define(name, constructor, options);

Parámetros

name
Nombre del nuevo elemento personalizado. Fíjate en que los nombres de elementos personalizados deben contener un guión.
constructor
Constructor para el nuevo elemento personalizado
options Optional
Objecto que controla cómo se define el elemento. Actualmente solo se permite una opción:
  • extends: Cadena que especifica el nombre del elemento preconstruido del cual se va a extender. Se usa para crear elementos personalizados preconstruidos.

Valor de retorno

Void.

Excepciones

Excepción Descripción
NotSupportedError El CustomElementRegistry ya contiene una entrada con el mismo nombre o el mismo constructor (o se ha definido ya de alguna otra manera), o se ha especificado extends pero el elemento del que se está intentando extender es desconocido.
SyntaxError El nombre proporcionado no es un nombre válido de elemento personalizado.
TypeError El constructor referenciado no es un constructor

Nota: A menudo se obtienen excepciones NotSupportedErrors cuando el método define() está fallando, pero realmente es un problema relacionado con Element.attachShadow().

Ejemplos

Elemento personalizado autónomo

El siguiente código está tomado de nuestro ejemplo popup-info-box-web-component  (verlo en vivo).

// Crear una clase para el elemento
class PopUpInfo extends HTMLElement {
  constructor() {
    // Siempre lo primero es llamar a super en el constructor
    super();

    // Crear una shadow root
    var shadow = this.attachShadow({mode: 'open'});

    // Crear tres elementos span
    var wrapper = document.createElement('span');
    wrapper.setAttribute('class','wrapper');

    var icon = document.createElement('span');
    icon.setAttribute('class','icon');
    icon.setAttribute('tabindex', 0);

    var info = document.createElement('span');
    info.setAttribute('class','info');

    // Coger el contenido del atributo text y ponerlo en el span info
    var text = this.getAttribute('text');
    info.textContent = text;

    // Coger el contenido del atributo img (si existe) y ponerlo en el span icon
    var imgUrl;
    if(this.hasAttribute('img')) {
      imgUrl = this.getAttribute('img');
    } else {
      imgUrl = 'img/default.png';
    }

    // El span no puede tener directamente una imagen, pero si contener un elemento img
    var img = document.createElement('img');
    img.src = imgUrl;
    icon.appendChild(img);

    // Crear los estilos CSS e incluirlos en el shadow DOM
    var style = document.createElement('style');

    style.textContent = '.wrapper {' +
                           'position: relative;' +
                        '}' +

                         '.info {' +
                            'font-size: 0.8rem;' +
                            'width: 200px;' +
                            'display: inline-block;' +
                            'border: 1px solid black;' +
                            'padding: 10px;' +
                            'background: white;' +
                            'border-radius: 10px;' +
                            'opacity: 0;' +
                            'transition: 0.6s all;' +
                            'position: absolute;' +
                            'bottom: 20px;' +
                            'left: 10px;' +
                            'z-index: 3;' +
                          '}' +

                          'img {' +
                            'width: 1.2rem' +
                          '}' +

                          '.icon:hover + .info, .icon:focus + .info {' +
                            'opacity: 1;' +
                          '}';

    // adjuntar los elementos creados (spans y estilo) al shadow DOM
    // notese que el span wrapper contiene los spans icon e info

    shadow.appendChild(style);
    shadow.appendChild(wrapper);
    wrapper.appendChild(icon);
    wrapper.appendChild(info);
  }
}

// Definir el nuevo elemento
customElements.define('popup-info', PopUpInfo);
<popup-info img="img/alt.png" text="Su código de validación de tarjeta (CVC) es una característica
                                    extra de seguridad — consiste en 3 o 4 
                                    numeros en la parte posterior de su tarjeta.">

Nota: Los constructores de elementos personalizados autónomos deben extender HTMLElement.

Elemento personalizado preconstruido

El siguiente código está tomado de nuestro ejemplo word-count-web-component (verlo en vivo).

// Crear una clase para el elemento
class WordCount extends HTMLParagraphElement {
  constructor() {
    // Siempre lo primero es llamar a super en el constructor
    super();

    // contar palabras del padre de este elemento
    var wcParent = this.parentNode;

    // la función countWords cuenta palabras (aunque estén separadas por más de un espacio)
    // que existe en el nodo pasado como parámetro. 
    // innerText está definido para objetos HTMLElement, mientras que textContent para todos los objetos Node 
    // el operador || hace que obtengamos al menos uno de los dos

    function countWords(node){
      var text = node.innerText || node.textContent
      return text.split(/\s+/g).length;
    }

    var count = 'Words: ' + countWords(wcParent);

    // // Crear una shadow root
    var shadow = this.attachShadow({mode: 'open'});

    // Crear un nodo span con el número de palabras
    var text = document.createElement('span');
    text.textContent = count;

    // Añadirlo a la shadow root
    shadow.appendChild(text);


    // Actualizar el contador cuando el contenido del elemento cambie
    setInterval(function() {
      var count = 'Words: ' + countWords(wcParent);
      text.textContent = count;
    }, 200)

  }
}

// Define the new element
customElements.define('word-count', WordCount, { extends: 'p' });
<p is="word-count"></p>

Especificaciones

Especificación Estado Comentario
HTML Living Standard
La definición de 'customElements.define()' en esta especificación.
Living Standard Initial definition.

Compatibilidad navegadores

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome para AndroidFirefox para AndroidOpera para AndroidSafari en iOSSamsung Internet
define
Experimental
Chrome Soporte completo 66
Notas
Soporte completo 66
Notas
Notas Support for 'Customized built-in elements' as well.
Soporte completo 54
Notas
Notas Support for 'Autonomous custom elements' only.
Edge Soporte completo 79
Notas
Soporte completo 79
Notas
Notas Support for 'Customized built-in elements' as well.
Soporte completo 79
Notas
Notas Support for 'Autonomous custom elements' only.
Firefox Soporte completo 63
Soporte completo 63
Sin soporte 59 — 63
Deshabilitado
Deshabilitado From version 59 until version 63 (exclusive): this feature is behind the dom.webcomponents.customelements.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
Sin soporte ? — 59
Deshabilitado
Deshabilitado Until version 59 (exclusive): this feature is behind the dom.webcomponents.enabled preference (needs to be set to true) and the dom.webcomponents.customelements.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Sin soporte NoOpera Soporte completo 53
Notas
Soporte completo 53
Notas
Notas Support for 'Customized built-in elements' as well.
Soporte completo 41
Notas
Notas Support for 'Autonomous custom elements' only.
Safari Soporte completo 10.1
Notas
Soporte completo 10.1
Notas
Notas Supports 'Autonomous custom elements' but not 'Customized built-in elements'
WebView Android Soporte completo 66
Notas
Soporte completo 66
Notas
Notas Support for 'Customized built-in elements' as well.
Soporte completo 54
Notas
Notas Support for 'Autonomous custom elements' only.
Chrome Android Soporte completo 66
Notas
Soporte completo 66
Notas
Notas Support for 'Customized built-in elements' as well.
Soporte completo 54
Notas
Notas Support for 'Autonomous custom elements' only.
Firefox Android Soporte completo 63
Soporte completo 63
Sin soporte 59 — 63
Deshabilitado
Deshabilitado From version 59 until version 63 (exclusive): this feature is behind the dom.webcomponents.customelements.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
Sin soporte ? — 59
Deshabilitado
Deshabilitado Until version 59 (exclusive): this feature is behind the dom.webcomponents.enabled preference (needs to be set to true) and the dom.webcomponents.customelements.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
Opera Android Soporte completo 47
Notas
Soporte completo 47
Notas
Notas Support for 'Customized built-in elements' as well.
Soporte completo 41
Notas
Notas Support for 'Autonomous custom elements' only.
Safari iOS Soporte completo 10.3
Notas
Soporte completo 10.3
Notas
Notas Supports 'Autonomous custom elements' but not 'Customized built-in elements'
Samsung Internet Android Soporte completo 9.0
Notas
Soporte completo 9.0
Notas
Notas Support for 'Customized built-in elements' as well.
Soporte completo 6.0
Notas
Notas Support for 'Autonomous custom elements' only.

Leyenda

Soporte completo  
Soporte completo
Sin soporte  
Sin soporte
Experimental. Esperar que el comportamiento cambie en el futuro.
Experimental. Esperar que el comportamiento cambie en el futuro.
Ver notas de implementación.
Ver notas de implementación.
El usuario debe de habilitar explícitamente esta característica.
El usuario debe de habilitar explícitamente esta característica.