DEV Community

Cover image for Scroll to top button with JQuery

Scroll to top button with JQuery

๐Ÿšฉ Atul Prajapati ๐Ÿ‡ฎ๐Ÿ‡ณ on May 30, 2022

Hello ๐Ÿ‘‹ dear techie friends, I am Atul Yesterday i have made a ๐Ÿญ simple scroll to top button with just HTML CSS. ...
Collapse
 
frankwisniewski profile image
Frank Wisniewski โ€ข โ€ข Edited

A few years ago I realized it as a plugin in vanilla.js

insert the following line before the closing body tag:

<script data-color=blue src="scrolltotop.js"></script>

The file scrolltotop.js:

(function(){
  const scrollScript = document.currentScript,
        scrollButtonColor = scrollScript.dataset.color || 'red',
        fhwScrollerDiv = document.createElement( 'div' ),
        scrollMe = () =>
          document.querySelector( 'body' )
            .scrollIntoView( { behavior: 'smooth' } )

  fhwScrollerDiv.innerHTML = `
    <svg width="50" height="50" viewbox="0 0 100 100">
      <circle  
        fill="${scrollButtonColor}" 
        cx="50" 
        cy="50" 
        r="50" 
      />
      <path 
        stroke="white" 
        stroke-width="16" 
        stroke-linecap="round" 
        d="M50 80 L50 20 M50 20 L80 50 M50 20 L20 50"
      />
      </svg>`;

  fhwScrollerDiv.style.cssText=`
    z-index:1000;
    position:fixed;
    bottom:20px;
    right:10px;
    cursor:pointer;
    display:none;`

  document.body.appendChild(fhwScrollerDiv);

  window.onscroll = function() {
      if (this.pageYOffset > 200) {
        fhwScrollerDiv.style.opacity = "0.5";
        fhwScrollerDiv.style.display = "block";
      } else {
        fhwScrollerDiv.style.opacity = "0";
        fhwScrollerDiv.style.display = "none";
      }
  }

  fhwScrollerDiv.querySelector('svg')
    .onmouseover = () => 
      fhwScrollerDiv.style.opacity = "1"

  fhwScrollerDiv.querySelector('svg')
    .onmouseout = () => 
      fhwScrollerDiv.style.opacity = "0.5"

  fhwScrollerDiv.onclick = scrollMe;  
})();  
Enter fullscreen mode Exit fullscreen mode
Collapse
 
eshimischi profile image
eshimischi โ€ข โ€ข Edited

This. ScrollIntoView (smooth) still in need of polyfill for legacy browsers tho

Collapse
 
Sloan, the sloth mascot
Comment deleted
 
atulcodex profile image
๐Ÿšฉ Atul Prajapati ๐Ÿ‡ฎ๐Ÿ‡ณ โ€ข

okay why not

Thread Thread
 
eshimischi profile image
eshimischi โ€ข

Well yes, but better add this one jsdelivr.com/package/npm/smoothscr... and use ScrollIntoView

Thread Thread
 
frankwisniewski profile image
Frank Wisniewski โ€ข

write your own Polyfill..

scrollMe = () => {
          if ( document.querySelector( 'body' ).scrollIntoView ){
            document.querySelector( 'body' )
              .scrollIntoView( { behavior: 'smooth' } )
          } else {
            let diff = document.documentElement.scrollTop || document.body.scrollTop;
            if (diff > 0) {
              window.requestAnimationFrame(scrollMe);
              window.scrollTo(0, diff - diff / 6);
            }
          }
        }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
atulcodex profile image
๐Ÿšฉ Atul Prajapati ๐Ÿ‡ฎ๐Ÿ‡ณ โ€ข

okay will do it

Collapse
 
atulcodex profile image
๐Ÿšฉ Atul Prajapati ๐Ÿ‡ฎ๐Ÿ‡ณ โ€ข

Oh that's great, I don't know about this. Thank you very much for sharing :)

lovely

Collapse
 
peerreynders profile image

Another stab at vanilla:

Modify:

<button id="topBtn">&#11014;</button>
Enter fullscreen mode Exit fullscreen mode

Modify:

:root {
  --fade-duration: 400ms;
}

#topBtn {
  --fade-duration: 0s;
  position: fixed;
  bottom: 40px;
  right: 40px;
  font-size: 2.5rem;
  width: 50px;
  height: 50px;
  background: #e74c3c;
  color: white;
  border: none;
  cursor: pointer;
  animation-name: fadeOut;
  animation-duration: var(--fade-duration);
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
}

@keyframes fadeOut {
  0% {
    visibility: visible;
    opacity: 1;
  }
  100% {
    visibility: hidden;
    opacity: 0;
  }
}

#topBtn.topBtn {
  animation-name: fadeIn;
  animation-duration: var(--fade-duration);
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
}

@keyframes fadeIn {
  0% {
    visibility: visible;
    opacity: 0;
  }
  100% {
    visibility: visible;
    opacity: 1;
  }
}
Enter fullscreen mode Exit fullscreen mode

Replace:

const BUTTON_ID = 'topBtn';
const DURATION_NAME = '--fade-duration';
const SHOW_BUTTON = 'topBtn';
const SCROLL_DURATION = 300;
const SCROLL_CYCLE = 15;

function initialize(_event) {
  const button = document.getElementById(BUTTON_ID);
  const showButton = (_event) => {
    if (window.scrollY > 40) button.classList.add(SHOW_BUTTON);
    else button.classList.remove(SHOW_BUTTON);
  };

  const scrollTarget = window;
  const scrollToTop = (event) => {
    let y = window.scrollY;
    const x = window.scrollX;
    const step = Math.floor((y * SCROLL_CYCLE) / SCROLL_DURATION);
    const nextStep = () => {
      y = step < y ? y - step : 0;
      window.scrollTo(x, y);
      if (y > 0) {
        setTimeout(nextStep, SCROLL_CYCLE);
        return;
      }
      scrollTarget.focus();
    };

    event.target.blur();
    nextStep();
  };

  // Enable animation after everything is loaded
  const rootStyle = getComputedStyle(document.documentElement);
  const duration = rootStyle.getPropertyValue(DURATION_NAME);
  button.style.setProperty(DURATION_NAME, duration);

  document.addEventListener('scroll', showButton);
  button.addEventListener('click', scrollToTop);
}

if (document.readyState === 'loading')
  document.addEventListener('DOMContentLoaded', initialize);
else initialize();
Enter fullscreen mode Exit fullscreen mode
Collapse
 
eshimischi profile image
eshimischi โ€ข

You donโ€™t need jQuery, try to make the same task with vanilla js

Collapse
 
shigetorum profile image
Edge โ€ข

The implementation seen is JQuery dependant, but I do agree that a Vanilla JavaScript implementation would've been more interesting.

Collapse
 
coderlifeisawesome profile image
lifeascoder โ€ข

Nice Work!

Collapse
 
atulcodex profile image
๐Ÿšฉ Atul Prajapati ๐Ÿ‡ฎ๐Ÿ‡ณ โ€ข

Thanks ๐Ÿ˜Š dear โ˜บ๏ธ