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>
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)
name
constructor
options
extends
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
innerText
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
showTime
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:
: chamado sempre que o elemento HTML personalizado é adicionado ao DOM.connectedCallback
: chamado sempre que o elemento HTML personalizado é removido do DOM.disconnectedCallback
: chamado sempre que o elemento HTML personalizado é movido para um novo documento.adoptedCallback
: chamado sempre que um atributo do elemento é adicionado, alterado ou removido.attributeChangedCallback
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()
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
this.style.color = "red";
if (this.hasAttribute("hellocolor")) {
this.style.color = this.getAttribute("hellocolor");
}
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>