Aguarde, carregando...

JS-0508 - JavaScript Completo ES6 - Animação de Números

JS-0508 - JavaScript Completo ES6 - Animação de Números
Publicado em 06/04/2021 10h46

Reagindo às mudanças do DOM com MutationObserver

Neste exemplo será implementado o efeito de animação de números, que aprecem em alguns sites, como um contador, alterando os números de forma crescente até um valor final.

Para este efeito, será aplicado o conceito do MutationObserver, uma interface do JS que permite o disparo de um evento diante alterações em um elemento. Esta interface substituiu o Mutation events, depreciado na atual ES.

Será utilizado o conteúdo do projeto para este exemplo. Caso queira o montar em seu ambiente de desenvolvimento, leia o conteúdo do JS-0302 - JavaScript Completo ES6 - Início do Projeto Prático.

HTML:

Como preparação, foi acrescida uma nova seção no projeto, após a seção "Contato", mantendo o padrão do projeto. A animação ao scroll será utilizada pelo observador. Esta nova seção, "Números", contém os valores para a manipulação. Datasets serão utilizados. O código do html é o seguinte:

JS-0508 - JavaScript Completo ES6 - Animação de Números 

CSS:

O estilo, utilizando o import padrão no style.css (@import 'numbers-animation.css';), foi definido da seguinte forma:

JS-0508 - JavaScript Completo ES6 - Animação de Números 

JavaScript:

Agora será aplicado o script que executará a animação dos números, utilizando modules. Foi confeccionado um novo arquivo .js, chamado de "numbers-animation", importado e ativado no no script principal:

JS-0508 - JavaScript Completo ES6 - Animação de Números

O primeiro passo é a seleção dos números pelo dataset em uma constante, utilizando o document.querySelectorAll('[data-number]').

Neste primeiro momento, para cada número selecionado, será extraído o valor deste com a propriedade innerText dentro de um forEach. Como cada valor obtido é uma string, houve a conversão para número através do "+". Para cada valor, este será atribuído a constante total.

O setInterval, com 25 milissegundos, foi utilizado para executar a variação de um contador, chamado de start, que é incrementado  em cada iteração e atribuído ao elemento selecionado com o innerText, até chegar no seu valor total. Quando o setInterval passa do valor total, a variável number receberá o seu valor inicial e então, será realizado o clearInterval sobre o counter.

Como os valores não são iguais, o efeito terminaria suas animações em momentos muito diferentes.

Para permitir uma aproximação, uma constante foi utilizada, increment, sendo esta dividida por 100. Também foi usado o Math.floor para retornar um número inteiro que será acrescido ao start. O divisor não poderá ser maior que o total de um número, pois vai retornar zero, e assim, nada será acrescido para este número específico. Para números altos, o intervalo pode ser multiplicado por Math.random(), para acelerar a contagem.

Até agora, o código está da seguinte forma:

JS-0508 - JavaScript Completo ES6 - Animação de Números

Ainda temos um problema, pois esta função é executada no momento do carregamento da tela e até chegar na seção de números o evento já ocorreu.

Esta função poderia ser ativada de várias formas no momento da visualização da seção alvo. Neste exemplo será utilizado um observador que estará atento às mudanças na seção.

Utilizando o MutationObserver:

O MutationObserver será instanciado em uma constante, chamada aqui de observer. Para utilizar esta inteface, é necessário um argumento, o callback que será ativo para realizar uma determinada ação. A função handleMutation será utilizada como o callback.

O objeto observer, instanciado do MutationObserver, precisa de um target e um valor deste para observar alterações, através do seu método observe(). A seção será o target do observer, sendo selecionada pela sua classe "numbers" e o atributo de section será utilizado como o parâmetro de observação.

A alteração do atributo da seção ocorre a cada evento de scroll, adicionado ou removendo a classe "active". Para o observer não ser disparado em qualquer movimento deste, a função animationScroll, será alterada, para remover a classe active somente quando esta existir em uma seção. O código do arquivo animation-scroll.js será alterado (somente o if para else if) para o seguinte:

JS-0508 - JavaScript Completo ES6 - Animação de Números

As mutações que ocorrem no target retornam uma lista de propriedades do objeto MutationRecord. Uma destas propriedades é o atributo monitorado ("attributes").

A imagem abaixo é um retorno do console.log sobre as mutações na função handleMutation:

JS-0508 - JavaScript Completo ES6 - Animação de Números

É preciso apenas checar se o target possui a classe active para disparar a função de animação utilizando a verificação mutation[0].target.classList.contains('active') em um "if", que retornará um true ou false para a existência da classe. Para o retorno true, será executado o efeito de animação. O código foi colocado dentro de uma função, chamada de initAnimation para poder ser ativada na função handleMutation.

Contudo, é preciso desativar o observador após o evento, pois a cada rolagem na seção alvo, ele permanecerá observando e ativando a função. Para realizar o encerramento da observação, existe um método de observer, o disconnect(). O código final ficou da seguinte forma:

JS-0508 - JavaScript Completo ES6 - Animação de Números

Para visualizar o resultado final, utilizando MutationObserver, clique aqui.

Para baixar o projeto, clique aqui.

Veja também:

Confira mais artigos relacionados

Este website utiliza cookies próprios e de terceiros a fim de personalizar o conteúdo, melhorar a experiência do usuário, fornecer funções de mídias sociais e analisar o tráfego. Para continuar navegando você deve concordar com nossa Política de Privacidade

Sim, eu aceito. Não, eu não aceito.