How to set the scrolling time of the page by clicking on the menu link and it redirects to a specific section? (with pure js)

Asked

Viewed 36 times

2

I made this js code for when click on the menu go to the section of the corresponding page (using the call by id). As the menu is fixed, in the script I discounted its height and its distance from the top to not overlap the section title. Now I’m trying to set the duration time to occur this scrolling. I only got by css, but no time control. If anyone can suggest something or see if the code can be more optimized:

    let menuLink = document.querySelectorAll('nav > ul > li > a');

menuLink.forEach((item) => {
    item.addEventListener('click', menuTop);
});

function menuTop(event) {
    event.preventDefault();

    let id = this.getAttribute('href');
    let alturaMenu = document.querySelector('nav > ul > li').scrollHeight;
    let topo = document.querySelector('nav').offsetTop;
    let distanciaTopo = document.querySelector(id).offsetTop - alturaMenu - topo;

    document.querySelector('html').scroll(0, distanciaTopo);
}

1 answer

2


Set the time maybe using some function with setInterval or setTimeout, but you can set a smooth scroll with a speed using this function:

function scrollSuave(old, des, atu){
    var easing = function (t) { return (--t)*t*t+1 };
    atu += 2; // move de 2 em 2 pixel. Aumentando o valor, irá aumentar a velocidade
    var ease = easing(atu/100);
    var del = des-old;
    del *= ease;
    del += old;
    document.querySelector('html').scrollTo(0, del);
    if(atu < 100){
      window.requestAnimationFrame(function (){
        scrollSuave(old, des, atu);
      });
    }
}

Notice on the line atu += 2; you can control scroll speed.

In the variable var easing you can define a type of easing (scroll style). In the above code is the easeOutCubic ((--t)*t*t+1), but you can test and choose other types available in this Github. Just replace only the snippet in the code (--t)*t*t+1 by the code of easing desired.

On the line document.querySelector('html').scroll(0, distanciaTopo) you replaced by function call:

scrollSuave(document.querySelector('html').scrollTop, distanciaTopo, 0);

Example:

let menuLink = document.querySelectorAll('nav > ul > li > a');

menuLink.forEach((item) => {
    item.addEventListener('click', menuTop);
});

function menuTop(event) {
    event.preventDefault();

    let id = this.getAttribute('href');
    let alturaMenu = document.querySelector('nav > ul > li').scrollHeight;
    let topo = document.querySelector('nav').offsetTop;
    let distanciaTopo = document.querySelector(id).offsetTop - alturaMenu - topo;

    scrollSuave(document.querySelector('html').scrollTop, distanciaTopo, 0);
}

// Função que faz o scroll suave
function scrollSuave(old, des, atu){
    var easing = function (t) { return (--t)*t*t+1 };
    atu += 2; // move de 2 em 2 pixel. Aumentando o valor, irá aumentar a velocidade
    var ease = easing(atu/100);
    var del = des-old;
    del *= ease;
    del += old;
    document.querySelector('html').scrollTo(0, del);
    if(atu < 100){
      window.requestAnimationFrame(function (){
        scrollSuave(old, des, atu);
      });
    }
}
body{
   margin: 0;
}

ul{
   list-style: none;
   margin: 0;
   height: 50px;
   display: flex;
}

li{
   height: 100%;
   margin-right: 30px;
   display: flex;
   align-items: center;
}

nav{
   background: yellow;
   position: fixed;
   width: 100%;
}
<nav>
   <ul>
      <li>
         <a href="#s1">Section 1</a>
      </li>
      <li>
         <a href="#s2">Section 2</a>
      </li>
   </ul>
</nav>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<section id="s1">
   section 1
</section>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<section id="s2">
   section 2
</section>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.