JSFiddle - React, Tailwind, and code Playground

by artgas_pro

HTML

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body class="body">
<header>
  <a class="ancor" href="#contacts">Contacts</a>
</header>
<section class="content">CONTENT</section>
<footer id="contacts">CONTACTS</footer>
</body>
</html>

CSS

.content{
  margin-top: 50px;
  height: 3000px;
}

JavaScript

document.addEventListener('click', documentActions);

function documentActions(e) {
      const target = e.target;
      if (!target.classList.contains('.ancor') && scroll == true){
           body.addEventListener('click', stopAnimation);
       }
}

function stopAnimation() { stop = true; console.log("listener work");}

let stop = false;
let scroll = false;
const body = document.querySelector(".body");

const scrolling = () => {
      
      const link = document.querySelector("[href='#contacts']");
      let speed = 0.3;


         link.addEventListener("click", function (event) {
            event.preventDefault();
            let widthTop = Math.round(
               document.documentElement.scrollTop || document.body.scrollTop
            ),
               hash = this.hash;
            let toBlock = document.querySelector(hash).getBoundingClientRect().top;
            let start = null;

            requestAnimationFrame(step);
            scroll = true;
            

            function step(time) {
               
               if (start === null) {
                  start = time;
               }
               let progress = time - start,
                  r =
                     toBlock < 0
                        ? Math.max(widthTop - progress / speed, widthTop + toBlock)
                        : Math.min(widthTop + progress / speed, widthTop + toBlock);

               let element = document.documentElement || document.body;
               element.scrollTo(0, r);

               if (r != widthTop + toBlock && !stop) {
                  requestAnimationFrame(step);
               } else {
                  body.removeEventListener('click', stopAnimation);
                  stop = false;
                  scroll = false;
               }
            }
         });
   };

   scrolling();