How to create a page scroll indicator with JavaScript

Create the cool scrolling indicator effect, print an horizontal line as the user scrolls down the page to indicate how further down they are.

HTML

Preferably at the top of your body, but not required.

<div class="pagescroll"></div>Code language: HTML, XML (xml)

CSS

Using CSS Variables, is this awesome or what?

.pagescroll {
  --scroll: 0%;

  position: fixed;
  top: 0;
  left: 0;
  height: 8px;
  width: 100%;
  background:
    linear-gradient(to right,
      red var(--scroll),
      transparent 0);
  z-index: 100;
}Code language: CSS (css)

JavaScript

It is important to throttle the scroll events, otherwise the CPU might slow down the client machine. Check out the included nonBlockingRepetiveFunctionCall function in the snippet below.

document.addEventListener("DOMContentLoaded", function (event) {
  /**
   * PAGE SCROLL EFFECT
   */
  const _timeoutIDs = {};

  function nonBlockingRepetiveFunctionCall(paramFunction, timeoutMs, functionID = ``) {
    if (!_timeoutIDs[paramFunction + functionID]) {
      // add timeout to not block the GUI
      _timeoutIDs[paramFunction + functionID] = window.setTimeout(() => {
        paramFunction();
        window.clearTimeout(_timeoutIDs[paramFunction + functionID]);
        _timeoutIDs[paramFunction + functionID] = undefined;
      }, timeoutMs);
    }
  }

  const $pagescroll = document.querySelector(".pagescroll");

  window.addEventListener('scroll', () => {
    if ($pagescroll) {
      nonBlockingRepetiveFunctionCall(() => {
        const scrollTop = document.documentElement["scrollTop"] || document.body["scrollTop"];
        const scrollBottom = (document.documentElement["scrollHeight"] || document.body["scrollHeight"]) - document.documentElement.clientHeight;

        scrollPercent = scrollTop / scrollBottom * 100 + "%";

        $pagescroll.style.setProperty("--scroll", scrollPercent);
      }, 10);
    }
  });
});Code language: JavaScript (javascript)

Demo

View demo

Leave a Reply

Your email address will not be published. Required fields are marked *