DEV Community

Valdeir S.
Valdeir S.

Posted on • Updated on

Web Components: Crie elementos personalizados com JavaScript

O que são (conceito)

Web Components são um conjunto de especificações elaboradas para permitir a criação de elementos web de forma customizada e independente.

Sites construídos com esse conceito tornam-se mais fáceis de manter, isto porque a alteração realizada num elemento será replicada em todo o site, facilitando as alterações e aumentando a produtividade.

A ideia não tão recente, surgiu por volta de 2011 numa conferência de Alex Russell, realizada na Fronteers Conference. Em 2012, começou a ganhar força com sua especificação de uso publicada no W3.

Apesar das diferenças, a chegada de novas bibliotecas — como a ReactJs e posteriormente a VueJs — ajudou a popularizar essa nova forma de programar, que visa separar e encapsular o site em pequenas estruturas.

As bibliotecas supramencionadas possuem técnicas e funcionamento diferentes se comparadas ao Web Componentes.

Atualmente, o conjunto de especificações é dividido em 3 peças (ou elementos).


Peças/Elementos

Peça 1) Shadow DOM

O DOM, na programação/marcação web, é uma API que nos permite acessar ou manipular documentos HTML (e XML). Cada um desses documentos é criado por uma árvore de nós com subnós.

Documento HTML

<!DOCTYPE html>
<html>
    <head>
        <title>Olá</title>
    </head>
    <body>
        <span style="color: red">Olá</span>
        <span>Mundo</span>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Árvore de nós do documento supra

Árvore de nós do documento

O ShadowDOM é semelhante ao DOM, a principal diferença está na capacidade que ele tem em definir o encapsulamento de uma árvore DOM, a fim de isolá-la do documento principal. Nos navegadores modernos, podemos ver essa técnica em vários elementos HTML.

O código <input type="date" />, por exemplo, gerará uma árvore encapsulada, que  — apesar de um CSS próprio  —  o código não interfere no restante do documento principal e também não é interferido.

Estrutura escondida do elemento input date

Peça 2) Custom Elements

Como o próprio nome diz, esta peça fornece aos desenvolvedores uma maneira de criar elementos HTML personalizados, incluindo visualmente e com eventos específicos.
Adotado pelo Chromium em 2014 em modo experimental, a versão 0 (V0)  — que foi descontinuada em 2016  —  não foi implementada por outros navegadores, que passaram a utilizar as especificações da V1.

Exemplificação

Exemplo utilizando o componente emoji-picker

Peça 3) Template

Esta é usada como um fragmento de documento (DocumentFragment). Apesar de ele ser adicionado no documento HTML, o navegador ignora-o durante a renderização. Via JavaScript, é possível clonar e/ou modificá-lo antes de o inserir na árvore DOM.

Slots

Elementos slot são usados dentro do elemento template para indicar onde determinado(s) conteúdo(s) será(ão) renderizado(s).

Vantagens e Desvantagem

Vantagens

  • Reutilização: Podemos utilizar o mesmo elemento em diversos lugares do projeto, de forma simples.
  • Produtividade: A alteração do visual, forma ou adição de novos elemento é facilitada.
  • Encapsulamento: Com um elemento encapsulado, é possível trabalhar com mais liberdade e evitando conflitos entre códigos.
  • Nomenclatura eficiente: O encapsulamento permite que os atributos como class e id possam ser objetivos.

Desvantagens

  • Compatibilidade: É possível usar algumas bibliotecas para tornar os elementos compatíveis com navegadores antigos, mas a falta de suporte nativo é uma desvantagem.
  • Semântica: Navegadores e buscadores não entendem o significado do elemento <emoji-picker />. Isso pode ser contornado para os buscadores e leitores de tela.
  • Acessibilidade: Os elementos nativos possuem uma série de atributos que são utilizados pelos leitores de tela; nos customizados, a sua atenção deverá ser redobrada. É possível melhorar e adaptar essa questão.
  • JavaScript: É necessário que o JavaScript esteja habilitado para o componente funcionar. Navegadores com o recurso desabilitado ou de linha de comando (Lynx, por exemplo) poderão não funcionar corretamente (mas nem o Xavier Vídeos funciona).

Criando o primeiro componente

No primeiro exemplo, será criado um componente bem simples, cujo objetivo é dar boas vindas ao usuário.

Base

Na linha 1, foi definido uma classe que estende os atributos e métodos da classe HTMLElement. Todo componente deve ser filho da HTMLElement, caso contrário o navegador não conseguirá executar e invocar os métodos necessários.

Na linha 2 e 3; foi, respectivamente, definida a função construtora e a invocação da função constructor da classe pai, que é obrigatória. A utilização da função constructor é opcional. Ela é chamada durante a criação ou atualização do componente e pode ser utilizada para criação do ShadowRoot, criação de eventos. No entanto, ao usá-la, é necessário saber que há algumas restrições, são elas:

  • A função super deve ser invocada logo após a criação do construtor;
  • É proibido retornar um valor, exceto return (void) ou return this;
  • A utilização das funções document.write e document.open é proibida;
  • Os atributos e filhos do elemento não devem ser inspecionados; O elemento não deve ganhar nenhum atributo ou filho. Essas alterações violam o método createElement ao ser usado para criação;
  • Evitem trabalhar com renderização no construtor, optem pelo método connectedCallback;

Na linha 5, criamos o ShadowRoot. Nele, vamos adicionar os elementos necessário para a renderização. Há dois modos possíveis:

  • open: Permite que o código exterior tenha acesso aos elementos do componente usando o atributo shadowRoot, por exemplo:
document
 .querySelector('v-welcome')
 .shadowRoot
 .querySelector('div')
Enter fullscreen mode Exit fullscreen mode
  • closed: Não permite que o código exterior tenha acesso aos elementos filhos do componente.

Na linha 8, foi definida a função attributesChangedCallback, que será invocada sempre que houver uma adição, atualização, remoção ou substituição de atributos. Para receber tais atualizações, é necessário reescrever o método estático observedAttributes e retornar um array de strings com os atributos que serão "ouvidos" (linhas 30, 31 e 32) do código Código 01 - Base.

Na linha 16, temos o método connectedCallback, que será invocado quando o componente for adicionado ao DOM. Este método é recomendado para execução de códigos de instalação e renderização.

O método disconnectedCallback, linha 26, é executado no momento que o elemento for removido do DOM. É ideal para remoção de eventos e limpeza do componente.

Na linha 35, foi definido o nome do componente e a classe responsável por ele. É importante o nome seguir a regra "caracteres-nome_do_componente", dessa forma o navegador identificará que é um componente customizado.

Utilizando componente

Neste tópico, serão abordadas duas formas de utilização.

Via HTML

No HTML, basta carregar o arquivo de script (o lugar não é tão importante para o funcionamento, pode ser dentro do <head> ou no final do <body>). Após carregá-lo, basta utilizar a tag com o nome definido no primeiro parâmetro da função window.customElements.define

Via JavaScript

Você também pode usar a função document.createElement para criar o elemento e node.setAttribute('atributo', 'valor') para definir os valores necessários.

Resultado

Exemplo Adicional

Este é um exemplo um pouco mais complexo. Nele, utilizando o elemento <v-image> para carregar um placeholder enquanto a imagem principal não é carregada. Também adicionamos suporte a alguns filtros e efeitos com CSS.

GitHub do Projeto

Conclusão

É isso! Os componentes estão aí para serem explorados e utilizados, obviamente dependendo do projeto e seu público alvo. Eles são uma mão na roda e realmente auxiliam bastante.

Caso tenham alguma dica ou sugestão, é só comentar. Agradeço-os pela leitura.


Projetos que utilizam Web Components

Links úteis

Referências

MDN (org.). Using custom elements. In: MOZILLA. Using custom elements. [S. l.], [20 - ]. Disponível em: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements. Acesso em: 3 jul. 2020.
WHATWG (org.). HTML: Scripting. [S. l.], [20 - ]. Disponível em: https://html.spec.whatwg.org/multipage/scripting.html. Acesso em: 8 jul. 2020.
WHATWG (org.). HTML: Custom elements. [S. l.], [20 - ]. Disponível em: https://html.spec.whatwg.org/multipage/custom-elements.html. Acesso em: 12 jul. 2020.
MDN (org.). Web Components: Using shadow DOM. [S. l.], [20 - ]. Disponível em: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM. Acesso em: 12 jul. 2020.
W3C (org.). Shadow DOM. [S. l.], [20 - ]. Disponível em: https://www.w3.org/TR/shadow-dom/. Acesso em: 3 jul. 2020.
HANASHIRO, Akira. O que é DOM, Virtual DOM e Shadow DOM?. [S. l.], 17 abr. 2020. Disponível em: https://www.treinaweb.com.br/blog/o-que-e-dom-virtual-dom-e-shadow-dom/. Acesso em: 16 jul. 2020.
GLAZKOV, Dimitri. What the Heck is Shadow DOM?. [S. l.], 14 jan. 2011. Disponível em: https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/. Acesso em: 16 jul. 2020.
https://github.com/mdn/web-components-examples

Top comments (0)