Atualizado: 07/12/2024

Criando Eventos Personalizados - JavaScript

A capacidade de disparar eventos programaticamente abre o caminho para a criação de eventos personalizados. Isso permite definir e disparar eventos arbitrários.

Por exemplo, temos a função construtora Account, que aceita uma quantia de dinheiro e cria uma conta monetária condicional:

function Account(money) {
    _money = money;
    this.pay = function(sum) {
        if (_money >= sum) {
            _money -= sum;
            console.log(_money);
        }
    }
}

A variável _money armazena a quantia de dinheiro atual na conta. Usamos a função pay para gastar uma certa quantia, se o saldo permitir. Suponha que precisamos notificar o sistema quando ocorrer um débito da conta. Poderíamos fazer isso diretamente no método pay usando console.log() para mostrar algum texto. Mas, no momento de escrever esse código, pode não ser claro qual texto exato deve ser exibido, ou talvez a notificação não deva aparecer no console, mas sim em uma janela do navegador ou ser enviada a um recurso de rede específico. A função construtora pode ser usada em Node.js, onde pode ser necessária uma abordagem diferente. Outros desenvolvedores que usarem nossa função podem ter suas próprias ideias sobre o que fazer quando os fundos são debitados. De qualquer forma, o principal é notificar o sistema que um débito ocorreu, e definir eventos personalizados pode ajudar a abordar todas essas situações.

Para definir eventos personalizados, podemos usar o construtor Event, ao qual passamos o nome do evento. Considere o seguinte programa:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Programício</title>
</head>
<body>
    <button id="btn">Pay</button>
    <script>
    const button = document.getElementById("btn");
    const myAcc = new Account(100); // conta monetária condicional
    // definindo um manipulador de eventos para todo o documento
    document.addEventListener("payment", () => console.log("Payment succeeded!"));
    
    // ao clicar no botão, executamos o método pay
    button.addEventListener("click", () => myAcc.pay(50));
    function Account(money) {
        _money = money;
        this.pay = function(sum) {
            if (_money >= sum) {
                _money -= sum;
                console.log(_money);

                const event = new Event("payment"); // definindo o objeto de evento
                document.dispatchEvent(event);     // disparando o evento para todo o documento
            }
        }
    }
    </script>
</body>
</html>

Criamos um objeto Event que representa o evento "payment" e depois disparamos esse evento.

Para manipular esse evento, nos inscrevemos nele:

document.addEventListener("payment", ()=>console.log("Payment succeeded!"));

A inscrição no evento é feita para todo o documento. O manipulador de eventos simplesmente exibe uma linha no console.

Ao pressionar o botão, chamamos o método pay do objeto myAcc e assim disparamos o evento "payment" (se houver fundos suficientes).

Para um teste mais robusto, pressionamos o botão:

Evento de bolha em JavaScript

Também podemos obter um objeto de evento no manipulador:

document.addEventListener("payment", (e) => {
    console.log(e.type); // payment
    console.log("Payment succeeded!");
});

CustomEvent

Embora possamos usar o tipo Event para definir eventos personalizados, ele não é ideal se quisermos passar informações adicionais para o manipulador de eventos, como a quantia debitada ou o saldo atual. Para esses casos, é melhor usar o tipo CustomEvent. Vamos modificar o código JavaScript da seguinte maneira:

const button = document.getElementById("btn");
document.addEventListener("payment", (e) => {
    console.log("Payment succeeded!");
    console.log("Payment Sum:", e.detail.paymentSum); // obtendo dados do evento
    console.log("Current balance:", e.detail.balance);
});

const myAcc = new Account(100);
// ao clicar no botão, executamos o método pay
button.addEventListener("click", () => myAcc.pay(50));

function Account(money) {
    _money = money;
    this.pay = function(sum) {
        if (_money >= sum) {
            _money -= sum;
            const event = new CustomEvent("payment", {
                detail: { // passando dados sobre o evento em CustomEvent
                    paymentSum: sum,
                    balance: _money
                }
            });
            document.dispatchEvent(event); // disparando o evento para todo o documento
        }
    }
}

No CustomEvent, passamos um objeto de configuração como segundo parâmetro, que possui a propriedade detail. Esta propriedade representa um objeto com um conjunto arbitrário de propriedades. Neste caso, definimos as propriedades paymentSum e balance e passamos os valores de interesse:

const event = new CustomEvent("payment", {
    detail: {
        paymentSum: sum,
        balance: _money
    }
});

Disparamos o evento CustomEvent da mesma maneira que o evento Event.

Ao processar o evento, podemos obter os dados transmitidos através da propriedade detail:

document.addEventListener("payment", (e) => {
    console.log("Payment succeeded!");
    console.log("Payment Sum:", e.detail.paymentSum); // obtendo dados do evento
    console.log("Current balance:", e.detail.balance);
});

Exemplo de saída no console após o primeiro clique no botão:

Payment succeeded!
Payment Sum: 50
Current balance: 50

Dessa maneira, podemos definir e gerenciar outros eventos também. Por exemplo, podemos definir outro evento caso não haja fundos suficientes para o pagamento:

const button = document.getElementById("btn");
document.addEventListener("payment_success", (e) => {
    console.log("Payment succeeded!");
    console.log("Payment Sum:", e.detail.paymentSum);
    console.log("Current balance:", e.detail.balance);
});
document.addEventListener("payment_fail", (e) => {
    console.error("Payment failed");
    console.error("Current balance:", e.detail.balance, "Requested Sum: ", e.detail.paymentSum);
});
const myAcc = new Account(100);
button.addEventListener("click", () => myAcc.pay(50));

function Account(money) {
    _money = money;
    this.pay = function(sum) {
        const data = {
            paymentSum: sum,
            balance: _money
        };
        if (_money >= sum) {
            _money -= sum;

            const event = new CustomEvent("payment_success", {
                detail: data
            });
            document.dispatchEvent(event);
        }
        else {
            const event = new CustomEvent("payment_fail", {
                detail: data
            });
            document.dispatchEvent(event);
        }
    }
}

Agora, se houver fundos suficientes na conta, o evento "payment_success" é disparado; se não houver, o evento "payment_fail" é disparado. Para cada um desses eventos, definimos um manipulador próprio.

Saída do console do programa (após três cliques no botão):

Payment succeeded!
Payment Sum: 50
Current balance: 100
Payment succeeded!
Payment Sum: 50
Current balance: 50
Payment failed
Current balance: 0 Requested Sum:  50
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