CustomElementRegistry.define()

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() (en-US).

Exemplos

Elemento personalizado autônomo

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

// 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);
<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.">

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).

 
    // 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' });
<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() (en-US) retorne um DOMException `NotSupportedError`.

    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

Especificação Estado Comentário
HTML Living Standard
The definition of 'customElements.define()' in that specification.
Padrão em tempo real Initial definition.

Compatibilidade com navegadores

BCD tables only load in the browser