CustomElementRegistry.define()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
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 Opcional
-
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 NotSupportedError
s 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."></popup-info>
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
Specification |
---|
HTML Standard # dom-customelementregistry-define-dev |
Compatibilidad con navegadores
BCD tables only load in the browser