Siphamandla

CROSSBROWSER SUPPORT VANILLA JAVASCRIPT ONLY SMOOTH PAGE SCROLL (SIMPLE STEPS)


Typical smooth page scroll make use Jquery library or other JS libraries, but this can be done easily with just few lines of vanilla JavaScript. In this demonstration I will show you how to build a animated smooth page scroll. Page scroll occurs when a user clicks to an anchor that has an href attribute with # and ID name of a certain element in the same web page.
VIEW DEMO DOWNLOAD SOURCE

I. HTML

1.HTML Mark-up

Let's begin with nav element with at least three anchor tags inside. Each anchor tag has a href attribute with a unique id name like href="#main-1" . main-1 is and ID name of an element in the same page which brings to second step which is to create three div elements. The first div will have main-1 as an ID name like id="main-1".

II. CSS

1.Full screen for divs

Let’s give 100% value for both width and height of all the three div tags. We will also give different background colour for each div tag, for demonstration. No you can see the scroll effect when you click on any of the anchor tags in the nav bar.

This is the normal scroll behaviour which occurs when the user clicks on link with href attribute which targets the id attribute name of the element inside the web page.

             
div{
 width:100%;
 height:100%;
 text-align: center;
}
div#main-1{background: blue;}
div#main-2{background: rgb(123, 123, 167);}
div#main-3{background: rgb(0, 162, 255);}                        

III. JavaScript

1.Find all anchor tags in Page

Let’s find all anchor tags in the web page and store the in constant variable - navLinks, using querySelectorAll.
Next, lets loop through navLinks array and store each anchor tag in variable named navLink using foreach() and check if any anchor is clicked by using add event listener for click event. Now if any of links in the nav is clicked, the function called smoothScroll is called.


//all anchor tags
const navLinks = document.querySelectorAll('a');

//naLink = each link in navLinks array
navLinks.forEach(navLink => navLink.addEventListener('click' , smoothScroll) );                     

2.Prevent Normal scroll behavior(non-smooth)

We will prevent the scroll behavior we have tested earlier because the whole point of this report is to animate the page scroll behavior for great user experience. See event.preventDefault(); //Prevent normal scrolling behavavior when anchor is clicked.


function smoothScroll(event){
  event.preventDefault();
}                    

3.Finding the vertical Position and height of scrolled element

First lets find out which element scrolled, the clicked has href attribute, inside that href there is an id name with # symbol eg href="#main-1". Lets use currentTarget.getAttribute to get that ID name,linkAttribute = event.currentTarget.getAttribute('href');.

Let's use querySelector to grab that id, like scrolledElement = document.querySelector(linkAttribute); .
Now let’s find the height from begin of the web page to when the page is current scrolled using offsetTop.Let's store this to variable named scrolledElHeight.

Let's find the current position vertically to which page is scrolled to. Let’s store this to variable named :- currentPosition.
Let's find difference between these heights and store it in variable called distance.

  
function smoothScroll(event){  
// ID in href attribute of current clicked anchor tag.                                
 linkAttribute = event.currentTarget.getAttribute('href');
 
 //query select the ID name found in href
 scrolledElement = document.querySelector(linkAttribute);

 //Height from begin of page towards scrolled height   
 scrolledElHeight = scrolledElement.offsetTop;  
 
 //current scrolled position
 const currentPosition = window.pageYOffset;    

 //difference
 const distance = scrolledElHeight - currentPosition;       
}                    

4.Use window.requestAnimationFrame() for Smooth Scroll

The function window.requestAnimationFrame() is used for animation, but it will need some parameters like animating duration and those three height mentioned above(the scrolledElHeight,currentPosition and distance).

Duration in this case is 500ms,but we will set counter to null see,let start = null;

window.requestAnimationFrame() take a function called step as a parameter. In the step function we have to conditions as if statement.

1.Check if the counter (start varible) is not null, if true take the value and store it in variable called timestamp.
The difference between timestamp and start time is our elapsed time frame, or progress.

2.if the progress time is not equal to duration(0.5s) ,we then keep running window.requestAnimationFrame(step)
Finally step is to use window.scrollTo() .Now this function will make use of those three height mentioned above(the scrolledElHeight,currentPosition and distance) in it's formula as parameters, see window.scrollTo( 0 , distance*(progress/duration) + currentPosition); .
The 0 parameter is for horizontal axes which are not required in this example.

This function will facilitate the scroll to desired element with help of window.requestAnimationFrame(step); for animation.


 // starting animation delay
 let start = null;                            
 
 //smooth animation delay 0.5seconds
 const duration = 500; 

 //animation function
 window.requestAnimationFrame(step);

function step(timestamp){
 
    //if start is null,let start = timestamp 
 if(!start) start  = timestamp; 
 //ellapsed time frame
 
 const progress = timestamp - start; 
 window.scrollTo( 0 , distance*(progress/duration) + currentPosition);

if(progress < duration){
//run requestAnimationFrame(step) until duration complete 
  window.requestAnimationFrame(step);         
 }
}