Criando Seu Próprio Elemento HTML - JavaScript

Por padrão, o HTML oferece uma série de elementos embutidos que podem ser utilizados para montar a estrutura de uma página web. Contudo, não estamos limitados apenas aos elementos HTML embutidos e podemos criar e utilizar nossos próprios elementos.

No JavaScript, um elemento HTML é representado pela interface HTMLElement. Implementando essa interface em JavaScript, podemos criar nossas próprias classes que representarão elementos HTML e, em seguida, utilizá-los em nossas páginas. Veja um exemplo abaixo:

<!DOCTYPE html>
<html>
  <head>
    <title>Programício</title>
    <meta charset="utf-8">
  </head>
  <body>
    <hello-programicio></hello-programicio>
  </body>
</html>

Neste caso, definimos um elemento <hello-programicio> na página, um elemento que ainda não existe. Mas vamos criá-lo agora.

Para definir uma classe que representará um elemento HTML, basta criar uma classe que implemente a interface HTMLElement:

class HelloProgramicio extends HTMLElement {
 
}

Um passo crucial é registrar o nosso elemento HTML personalizado para que o navegador reconheça sua existência. Utilizamos a função embutida customElements.define(name, constructor, options); que aceita três parâmetros:

    name: nome do elemento HTML personalizado, que deve conter um hífen.

    constructor: o construtor da classe JavaScript que representa o elemento HTML.

    options: um parâmetro opcional que configura o elemento HTML personalizado. Atualmente, suporta um parâmetro, extends, que especifica o nome de um elemento HTML embutido que é usado para criar o elemento personalizado.

Por exemplo:

customElements.define("hello-programicio", HelloProgramicio);

A implementação completa seria:

<!DOCTYPE html>
<html>
<head>
<title>Programício</title>
<meta charset="utf-8">
</head>
<body>
<hello-programicio></hello-programicio>
<script>
class HelloProgramicio extends HTMLElement {
    constructor() {
        super(); // garante que todos os métodos e propriedades do HTMLElement sejam herdados
        let welcome = "Bom dia";
        const hour = new Date().getHours();
        if (hour > 17) {
            welcome = "Boa noite";
        } else if (hour > 12) {
            welcome = "Boa tarde";
        }
        this.innerText = welcome;
    }
}
customElements.define("hello-programicio", HelloProgramicio);
</script>
</body>
</html>

No construtor, obtemos a hora atual e definimos uma saudação apropriada dependendo da hora do dia. Como nossa classe implementa a interface HTMLElement, podemos usar propriedades padrão para elementos HTML, como innerText para definir o texto do elemento.

Adicionando Métodos a Elementos Personalizados

Assim como em classes comuns, podemos definir métodos nas classes de elementos e chamá-los posteriormente. Vamos definir um método simples que retorna a hora atual:

<!DOCTYPE html>
  <html>
  <head>
  <title>Programício</title>
  <meta charset="utf-8">
  </head>
  <body>
  <hello-programicio id="hello"></hello-programicio>
  <script>
  class HelloProgramicio extends HTMLElement {
      constructor() {
          super();
          let welcome = "Bom dia";
          const hour = new Date().getHours();
          if (hour > 17) {
              welcome = "Boa noite";
          } else if (hour > 12) {
              welcome = "Boa tarde";
          }
          this.style = "cursor: pointer;";
          this.innerText = welcome;
      }
      showTime() {
          console.log(new Date().toTimeString());
      }
  }
  customElements.define("hello-programicio", HelloProgramicio);
  const hello = document.getElementById("hello");
  hello.addEventListener("click", () => hello.showTime());
  </script>
  </body>
  </html>
  

Neste exemplo, o método showTime simplesmente exibe a hora atual no console. No código JavaScript, obtemos o elemento pelo ID e anexamos um manipulador de eventos que chama o método showTime ao clicar no elemento, mostrando a hora atual no console.

Criação de Elemento HTML, HTMLElement e customElements.define

Eventos do Ciclo de Vida de Elementos HTML Personalizados

Um elemento HTML personalizado possui seu próprio ciclo de vida, que é descrito pelos seguintes métodos:

  • connectedCallback: chamado sempre que o elemento HTML personalizado é adicionado ao DOM.

  • disconnectedCallback: chamado sempre que o elemento HTML personalizado é removido do DOM.

  • adoptedCallback: chamado sempre que o elemento HTML personalizado é movido para um novo documento.

  • attributeChangedCallback: chamado sempre que um atributo do elemento é adicionado, alterado ou removido.

Por exemplo, vamos aplicar o método connectedCallback():

<!DOCTYPE html>
  <html>
  <head>
  <title>Programício</title>
  <meta charset="utf-8">
  </head>
  <body>
  <hello-programicio id="hello"></hello-programicio>
  <script>
  class HelloProgramicio extends HTMLElement {
      constructor() {
          super();
          let welcome = "Bom dia";
          const hour = new Date().getHours();
          if (hour > 17) {
              welcome = "Boa noite";
          } else if (hour > 12) {
              welcome = "Boa tarde";
          }
          this.style.cursor = "pointer";
          this.innerText = welcome;
      }
      connectedCallback() {
          this.style.color = "red";
      }
      showTime() {
          console.log(new Date().toTimeString());
      }
  }
  customElements.define("hello-programicio", HelloProgramicio);
  </script>
  </body>
  </html>

Neste caso, no método connectedCallback(), simplesmente definimos a cor do texto para vermelho:

this.style.color = "red";

Adicionando Atributos

<!DOCTYPE html>
<html>
<head>
<title>Programício</title>
<meta charset="utf-8">
</head>
<body>
<hello-programicio hellocolor="green"></hello-programicio>
<br/>
<hello-programicio></hello-programicio>
<script>
class HelloProgramicio extends HTMLElement {
    constructor() {
        super();
        let welcome = "Bom dia";
        const hour = new Date().getHours();
        if (hour > 17) {
            welcome = "Boa noite";
        } else if (hour > 12) {
            welcome = "Boa tarde";
        }
        this.style.cursor = "pointer";
        this.innerText = welcome;
    }
    connectedCallback() {
        this.style.color = "red";
        if (this.hasAttribute("hellocolor")) {
            this.style.color = this.getAttribute("hellocolor");
        }
    }
    showTime() {
        console.log(new Date().toTimeString());
    }
}
customElements.define("hello-programicio", HelloProgramicio);
</script>
</body>
</html>

Neste caso, o elemento aceita o atributo hellocolor, que define a cor do texto do elemento. Se este atributo estiver definido, a cor do texto será ajustada de acordo. Se não estiver definido, será utilizada a cor padrão, que é vermelha:

this.style.color = "red";
if (this.hasAttribute("hellocolor")) {
    this.style.color = this.getAttribute("hellocolor");
}
Atributos de Elemento HTML, HTMLElement e customElements.define e connectedCallback

Estilização CSS

A estilização de um elemento através do CSS é realizada da mesma forma que a estilização de qualquer outro elemento:

<!DOCTYPE html>
<html>
<head>
<title>Programício</title>
<meta charset="utf-8">
<style>
hello-programicio {
    font-family: Verdana;
    font-size: 22px;
}
</style>
</head>
<body>
<hello-programicio hellocolor="green"></hello-programicio>
<script>
class HelloProgramicio extends HTMLElement {
      
    constructor() {
        super();
          
        let welcome = "Bom dia";
        const hour = new Date().getHours();
        if (hour > 17) {
            welcome = "Boa noite";
        } else if (hour > 12) {
            welcome = "Boa tarde";
        }
        this.style.cursor = "pointer";
        this.innerText = welcome;
    }
    connectedCallback() {
        this.style.color = "red";
        if (this.hasAttribute("hellocolor")) {
            this.style.color = this.getAttribute("hellocolor");
        }
    }
    showTime() {
        console.log(new Date().toTimeString());
    }
}
  
customElements.define("hello-programicio", HelloProgramicio);
</script>
</body>
</html>
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com