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.

* Some parts of this feature may have varying levels of support.

O método define() da interface CustomElementRegistry define um novo elemento personalizado.

Dois tipos de elementos personalizados podem ser criados:

  • Elementos personalizados autônomos: Elementos autônomos; estes herdam de HTMLElement (Elemento HTML genérico).
  • Elementos personalizados pré-construídos: Estes elementos herdam - e estendem - elementos HTML já existentes (p.ej HTMLParagraphElement que é um elemento HTML <p>).

Sintaxe

customElements.define(name, constructor, options);

Parâmetros

name

Nome do novo item personalizado. Observe que os nomes dos elementos personalizados devem conter um hífen.

constructor

Construtor para o novo elemento personalizado

options Optional

Um objeto que controla como o elemento é definido. Atualmente, apenas uma opção é permitida:

  • extends: String que especifica o nome do elemento pré-definido a partir do qual se estende. Usado para criarelementos personalizados pré-construídos.

Valor de retorno

Void.

Exceções

Exceção Descrição
NotSupportedError El CustomElementRegistry já contém uma entrada com o mesmo nome ou o mesmo construtor (ou já foi definido de alguma outra forma), ou foi especificado extends mas o elemento do qual você está tentando estender é desconhecido.
SyntaxError O nome fornecido não é um nome de elemento personalizado válido.
TypeError O constructor referenciado não é um constructor

Nota: Exceções são frequentemente obtidas NotSupportedErrors quando o método define() está falhando, mas é realmente um problema relacionado a Element.attachShadow().

Exemplos

Elemento personalizado autônomo

O código a seguir é retirado do nosso exemplo popup-info-box-web-component (ver ao vivo).

js
// Crie uma classe para o elemento
class PopUpInfo extends HTMLElement {
  constructor() {
    // Sempre a primeira coisa a fazer é chamar super no construtor
    super();

    // crie um shadow root
    var shadow = this.attachShadow({ mode: "open" });

    // Crie três 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");

    // Pegue o conteúdo do atributo de texto e coloque-o no span info
    var text = this.getAttribute("text");
    info.textContent = text;

    // Pegue o conteúdo do atributo img (se existir) e coloque-o no ícone de span
    var imgUrl;
    if (this.hasAttribute("img")) {
      imgUrl = this.getAttribute("img");
    } else {
      imgUrl = "img/default.png";
    }

    // A extensão não pode ter diretamente uma imagem, mas se contiver um elemento img
    var img = document.createElement("img");
    img.src = imgUrl;
    icon.appendChild(img);

    // Crie os estilos CSS e inclua-os no 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;" +
      "}";

    // anexar os elementos criados (extensões e estilo) ao shadow DOM
    // observe que o span wrapper contém o ícone e os spans de informações

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

// Defina um novo elemento
customElements.define("popup-info", PopUpInfo);
html
<popup-info
  img="img/alt.png"
  text="O código de validação do seu cartão (CVC) é um recurso segurança extra - consiste em 3 ou 4 números no verso do seu cartão."></popup-info>

Nota: Construtores de elementos personalizados autocontidos devem estender HTMLElement.

Elemento personalizado pré-construído

O código a seguir é retirado do nosso exemplo word-count-web-component (ver ao vivo).

js
// Crie uma classe para o elemento
class WordCount extends HTMLParagraphElement {
  constructor() {
    // Sempre a primeira coisa a fazer é chamar super no construtor
    super();

    // contar palavras do pai deste elemento
    var wcParent = this.parentNode;

    // A função countWords conta palavras (mesmo que sejam separadas por amis de um espaço)
    // que existe no nó passado como parâmetro.
    // innerText está definido para objetos HTMLElement, enquanto textContent para todos os objetos Node
    // o operador || nos faz pegar pelo menos um dos dois

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

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

    // crie um shadow root
    var shadow = this.attachShadow({ mode: "open" });

    // Crie um nó span com o número de palavras
    var text = document.createElement("span");
    text.textContent = count;

    // Adicione ao shadow root
    shadow.appendChild(text);

    // Atualize o contador quando o conteúdo do elemento mudar
    setInterval(function () {
      var count = "Words: " + countWords(wcParent);
      text.textContent = count;
    }, 200);
  }
}

// Defina o novo elemento
customElements.define("word-count", WordCount, { extends: "p" });
html
<p is="word-count"></p>

Criando elemento que desativa a capacidade de utilizar attach no shadow root

Se a classe usada para o elemento contém a propriedade estática disabledFeatures retornando a string "shadow" isso fará com que Element.attachShadow() retorne um DOMException NotSupportedError.

js
class PopUpInfo extends HTMLElement {
  static get disabledFeatures() {
    return ["shadow"];
  }

  constructor() {
    super();

    var shadow = this.attachShadow({ mode: "open" });
    // isso fará com que um erro seja lançado quando o elemento for definido.
  }
}

Especificações

Specification
HTML
# dom-customelementregistry-define-dev

Compatibilidade com navegadores

Report problems with this compatibility data on GitHub
desktopmobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
define
Supports disabledFeatures static property

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support