Efeito Scroll Suave (Scroll smooth)
Tags: javascript, webdev, programming, tutorial
Published: 2021-12-03 07:45:30


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxo5jf7idorsue0sqo46.gif)
**Premissa:**
Antes mesmo de navegarmos nesse grande mar de códigos e explicações, gostaria de ser seguro que você esteje completamente ciente que o nosso foco principal será explicar os conceitos de JavaScript, portanto se tiveres problemas em entender html e alguns conceitos básicos de JavaScript, por favor este tutorial não será muito útil para você, ao contrário, será provavelmente uma frustração. 



dito isso, gostaria de listar aqui o nosso código html, compreende-o fortemente antes mesmo que eu o explique e assim ajudará você também a ter uma melhor compreensão do conteudo.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2h52rcje993n4i0567d.png)
_descrição:imagem-1_

> 
a imagem acima apresenta o nosso botão que servirá como elemento a ser clicado e posteriormente nos levará até a secção desejada.

> 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1qrdmata7tep3mhpr18.png)
_descrição:imagem-2_

> 
a imagem acima refere-se a secção na qual queremos chegar com o nosso scroll suave uma vez clicado ao nosso botão descrito na imagem-1.
> 



Tendo o nosso código html efeito, agora é necessário selecionarmos estes dois elementos, o botão (descrito na imagem-1) e a secção (section descrito na imagem-2) no nosso javascript, para isso devemos usar seguir os seguintes passos:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4eif6rdbz8tvmbltwgez.png)
_descrição:imagem-3_

> 
como você vê, a ideia é selecionar os dois elementos no qual precisaremos, o botão, que servirá para aplicarmos o evento, a secção (section), que ouvirá e executará esse evento através de uma função contendo as instruções necessárias
> 

Agora que estamos prontos com as ideias fundamentais que giram em torno do nosso desafio de hoje, por favor entre no barco e vamos navegar por mais de 3000 mil milhas da costa.



Para a aplicação do nosso efeito scroll suave (scroll smooth) existe duas técnicas bastante usadas que são:

   1. 
   **Usando coordenadas explicitas (scrollTo(object))**

   2. 
  **Usando coordenadas implícitas (scrollIntoView(object))**




 

#### Usando coordenadas explicitas (scrollTo(object))

 A primeira ideia sobre essa técnica é obtermos coordenadas do nosso elemento no qual queremos que a nossa barra de rolagem tenha como destino, Em nosso caso será a nossa **section1**.É importante realçar que está técnica é bastante antiga e ela comporta um custo computacional alto, mas para fins didáticos e também por compatibilidade com alguns browsers antigos que não suportam a nova técnica que veremos posteriormente, decidi trazer ela para um estudo.
Sendo que a ideia é ter as coordenadas X e Y da nossa **section1**, existe um método do nosso próprio elemento que se chama **getBluidingClientReact()** que obtém os valor das coordenadas desejada, este método nos retorna um objeto **DOMRect**  que contém várias propriedades, mas para o nosso estudo estaremos interessados em utilizar as propriedades Left e Top. Left representa a coordenada no eixo X, ou seja ela representa a distância no eixo X entre o elemento clicado(botão) até ao elemento na qual queremos rolar (section1) no eixo X do plano cartesiano, e o Top representa a coordenada do eixo Y, ou seja ela representa a distância no eixo Y entre o elemento clicado (Botão) até ao elemento na qual queremos rolar (section1) no eixo Y do plano cartesiano.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijm2t33pyvg2rlu2lpzg.jpg)
_descrição:imagem-4_

> 
Com um mínimo de matemática básica conseguimos perceber e ter uma ideia sobre os nossos dois eixos (X,Y).
> 

Se notarmos com atenção o nosso eixo X representado por Left, o seu valor será zero porque o elemento ocupa toda página e esse valor permanece inalterável, Já o eixo  Y representado por Top o seu valor vai mudando  em função da nossa barra de rolagem, quando o scroll(barra de rolagem) chega até a section1 o Top (eixo Y) assume valor 0 simbolizando assim que chegamos ao lugar desejado. Tendo em posse esses dois valores, nos é hora de aplicar esses valores em nosso objeto **windows**, porque é este objeto que controla a nossa barra de rolagem. para isso, basta usarmos um método do nosso objeto windows chamado scrollTo() passando um objecto que recebe as nossas coordenadas e uma propriedade especial chamada **behavior** que terá como valor **smooth**.

_obs:_

> 
A propriedade **behavior** recebe dois valores, um é o **auto**, que representa o comportamento padrão das barraras de rolagem de um navegador, já o **smooth** torna a rolagem da barra suave. 
> 
 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gdpmo799lhwytd4mpgc5.png)
_descrição:imagem-5_

> 
Aplicando o evento click ao botão e executado a função callback para realização do nosso efeito.

> 

Ok, agora parece que chegamos ao fim do nosso trabalho, mas não, infelizmente não, com um pouco mais de atenção percebemos que temos que resolver ainda mais um pequeno problema, que problema? Se eu quando faço click ao botão me leva a secção deseja e com efeito do scroll suave. Realmente só com essas linhas de códigos o nosso efeito já funciona, mas se redimensionarmos o nosso browser no eixo Y perceberás que não teremos o resultado esperado. Mas qual é o motivo deste comportamento?
Bem, o nosso problema existe pelo facto que as nossas viewport dos browsers têm dimensões relativas e não fixas, e cada vez que eu altero a dimensão do nosso browser a nossa viewport muda as suas dimensões. Uma outra causa clara sobre isso, é a existência de vários dispositivos que executarão o nosso programa, visto que elas possuem dimensões diferentes em base ao dispositivo que estamos usando, então também nos pode gerar esse problema.
_Exemplo:_ 

> 
uma viewport de um smartphone Galaxy não é igual a de um computador ou iPhone.

> 
Agora que identificamos o nosso problema, a nossa solução passa por ter mais outras duas coordenadas que representam a nossa viewport com valores relativos, para isso temos  duas propriedades do objeto windows  que retornam os valores das coordenadas X e Y da nossa viewport e posteriormente esses valores devem ser somando com as coordenadas vinda do nosso elemento (section1), ou seja, a coordenada Y retornada do objeto window deve somar com a coordenada Y do nosso elemento, e a coordenada X  retornada do objeto window deve somar com a coordenada X do nosso elemento.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5actm3t2egpt5vn5fcu.png)

_descrição:imagem-6_

> 
Window.pageXOffset = coordenada X da janela (Windows = viewport) 
Window.pageYOffset = coordenada Y da janela (Windows = viewport)

> 


#### Usando coordenadas implícitas (scrollIntoView(object))

Antes de explicar o uso da segunda técnica gostaria de fazer uma premissa muito importante, O uso deste método é recente, e para browsers antigos possivelmente não funcionará por não terem suporte ao mesmo, por isso antes do uso do mesmo é necessária uma verificação onde o seu serviço poderá ser consumido, assim poderás evitar qualquer problema de funcionamento, você pode der essa informação visitando o **can I use** para ter ideia do suporte na data atual em que você lê este artigo, mas contudo deixarei aqui também uma imagem da visita feita no can I use com o suporte da data atual. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lple2iz0sa04pp66vgtz.png)
_descrição:imagem-7_

> 
Consulta no **can I use** para verificar o suporte do método scrollIntoView nos browsers.

> 

Depois dessa pequena observação gostaria de dizer que este método é ainda mais fácil do que o primeiro, porque com este método não nos preocupamos em ter essas coordenadas que parecem extremamente tediosa de entender, a ideia primaria é ter a referência do elemento no qual queremos que o nosso scroll vá suavemente depois do click, Posteriormente devemos pegar esse elemento e executar simplesmente um seu método  chamado scrollIntoView passando como parâmetro do método um objeto com a propriedade behavior tendo o valor smooth.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yf30psq7lrh4zyqe65zg.png)
_descrição:imagem-8_

> 
Executando o nosso efeito só com uma linha de código 
> 


Simplesmente fácil e satisfatório, neste tutorial não mexemos com o delay na qual o scroll poderia ter para chegar ao elemento desejado, mais nos próximos artigos espero trazer isso pra vocês de uma maneira mais simples de se implementar, mas sem esquecer os fundamentos por trás. Sei que não nos convém refazer a roda, mas é necessário saber com que material é feito e como é feito para que saibamos escolher uma boa roda e distinguir ela no meio de qualquer coisa circular com a mesma cor.

_author: Jeft F. Matamba_