Adding Scroll To Top In WordPress Site

Scroll To Top Button

<div id="footer-wrapper" class=" text-white footer-wrapper">
<footer id="colophon" class="site-footerpt-50px pb-43px lg:pt-85px lg:pb-74px">

<div class="back-to-top">
<button id="back-to-top">
<svg class="w-6 h-6 transform -rotate-90" id="icon-arrow-heavy" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13 7v-6l11 11-11 11v-6h-13v-10z"/>
</svg>
<span><?php esc_html_e( 'go to top', 'text-domain' ); ?></span>
</button>
</div>
</div><!-- #footer-wrapper -->
<?php

wp_footer();
?>
</body>
</html>

InViewPortAnimation

$ = jQuery;

$.fn.extend( {
getPath: function () {
let path, node = this;
while ( node.length ) {
var realNode = node[0], name = realNode.nodeName;
if ( ! name ) {
break;
}

name = name.toLowerCase();

let parent = node.parent();

let sameTagSiblings = parent.children( name );
if ( sameTagSiblings.length ) {
let allSiblings = parent.children();
let index = allSiblings.index( realNode ) + 1;
if ( index > 1 ) {
name += ':nth-child(' + index + ')';
}
}

path = name + ( path ? '>' + path : '' );
node = parent;
}

return path;
}
} );

/**
* Used to attach to a element to always watch if its in the viewport.
*
* When scrolling, if element is in viewport add a parameter, a data attribute and a class name.
*/
export class InViewportAnimation {
_elements;

constructor() {
this.boundScrollEvent = false;
this.elements = {};
this.selectors = '';

const that = this;

that.selectors = selectors;
that.scroll();
that.checkElements();
that.toggleClasses();
}

addElement( element ) {
if ( $( element ).length ) {
if ( 'undefined' !== typeof this.elements[ $( element ).getPath() ] ) {
return;
}

$( element ).toggleClass( 'initiate-scroll-animation', true );
this.elements[ $( element ).getPath() ] = element;
}
}

setClasses( elem ) {
const inViewport = this.inViewport( elem );
elem.inViewport = inViewport;
elem.attr( 'data-in-viewport', inViewport ).toggleClass( 'in-viewport', inViewport );

this.setInlineClasses( inViewport, elem );
}

setInlineClasses( inViewport, elem ) {
if ( ! inViewport ) {
elem.css( { opacity: '0.5', transform: 'translateY(15px)', transition: '1s transform ease, 1s opacity ease' } );
} else {
elem.css( { opacity: '1', transform: 'translateY(0)', transition: '1s transform ease, 1s opacity ease' } );
}
}

checkElements() {
$( this.selectors ).each( ( i, elem ) => {
this.addElement( elem );
} );
}

scroll() {
if ( ! this.boundScrollEvent ) {
$( window ).on( 'scroll', () => {
this.checkElements();
this.toggleClasses();
} );
this.boundScrollEvent = true;
}
}

toggleClasses( elem = false ) {
if ( ! elem ) {
if ( ! Object.keys( this.elements ).length ) {
return;
}

Object.keys( this.elements ).forEach( ( path ) => {
if ( 'skip' === this.elements[ path ] ) {
return;
}

const elem = $( this.elements[ path ] );
const inViewport = this.inViewport( elem );
elem.inViewport = inViewport;
elem.attr( 'data-in-viewport', inViewport ).toggleClass( 'in-viewport', inViewport );

this.setInlineClasses( inViewport, elem );

if ( inViewport ) {
this.elements[ path ] = 'skip';
}
} );
} else {
const inViewport = this.inViewport( elem );
elem.inViewport = inViewport;
elem.attr( 'data-in-viewport', inViewport ).toggleClass( 'in-viewport', inViewport );

this.setInlineClasses( inViewport, elem );
}
}

inViewport( elem ) {
return this.elementBottom( elem ) > this.viewportTop() && this.elementTop( elem ) < this.viewportBottom();
}

elementBottom( elem ) {
return this.elementTop( elem ) + $( elem ).outerHeight();
}

viewportTop() {
return $( window ).scrollTop();
}

elementTop( elem ) {
return $( elem ).offset().top;
}

viewportBottom() {
return this.viewportTop() + $( window ).height();
}
}

Debounce function

/**
* Calls the given function after the given interval.
*
*
@param {Object} func Function name.
*
@param {number} wait Time in milliseconds.
*
*
@return {Function} Debounced function.
*/
export const debounce = ( func, wait ) => {

let timeout;

/**
* Debounce function.
*/
return function() {

const context = this,
args = arguments;

/**
* Later function.
*/
const later = function() {
timeout = null;
func.apply( context, args );
};

clearTimeout( timeout );

timeout = setTimeout( later, wait );
};

};

Scroll To Top Main JS file

/**
* Back to Top.
*
*
@package WPR
*/

import { debounce } from "./functions";
import { InViewportAnimation } from './in-viewport-animation';

( function ( $ ) {
class BackToTop {

/**
* Constructor.
*
*
@return {void}
*/
constructor() {

this.backToTopEl = $( '#back-to-top' );
this.siteFooter = $( 'footer#colophon.site-footer' );
this.window = $( window );

// The window scroll position after which we show the scroll to top button.
this.scrollOffset = 200;

if ( ! this.backToTopEl ) {
return;
}

this.addEvents();

}

addEvents() {

this.backToTopEl.on( 'click', this.scrollWindowToTop );
this.window.on( 'scroll', () => debounce( this.toggleScrollToTopBtnVisibilty(), 1000 ) );

new InViewportAnimation();
}

/**
* Toggle scroll button visibility.
*
* When the scroll position is large than scrollOffset
* we will show the scroll to top button,
* else hide it.
*
*
@return {void}
*/
toggleScrollToTopBtnVisibilty() {

// If the scroll position is larger than scrollOffset.
if ( window.scrollY > this.scrollOffset ) {
this.backToTopEl.addClass( 'is-visible' );

const top_of_element = this.siteFooter.offset().top;
const bottom_of_element = this.siteFooter.offset().top + this.siteFooter.outerHeight();
const bottom_of_screen = $( window ).scrollTop() + $( window ).innerHeight();
const top_of_screen = $( window ).scrollTop();

if ( ( bottom_of_screen > top_of_element ) && ( top_of_screen < bottom_of_element ) ) {
const diff = bottom_of_screen - top_of_element;
this.backToTopEl.parent( '.back-to-top' ).css( 'bottom', ( 20 + diff ) + 'px' );
} else {
this.backToTopEl.parent( '.back-to-top' ).css( 'bottom', '20px' );
}
} else {
this.backToTopEl.removeClass( 'is-visible' );
}
}

/**
* Scroll window to top.
*
* When the back to top button is clicked scroll to top position.
*
@return {void}
*/
scrollWindowToTop() {
window.scrollTo( {
top: 0,
behavior: 'smooth'
} );
}

}

new BackToTop();

} )( jQuery );

Scroll To Top CSS

.back-to-top {
display: none;

@screen lg {
position: fixed;
bottom: 20px;
right: 0;
align-items: center;
margin: auto;
height: 140px;
width: 100px;
justify-content: center;
z-index: 3;
display: flex;
}

button {
display: flex;
flex-direction: column;
align-items: center;
color: #d5d7d8;
cursor: pointer;
font-style: normal;
font-weight: 400;
font-size: 12px;
line-height: 137.74%;
border-color: transparent;
background-color: transparent;
opacity: 0;
-ms-user-select: none;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
transition: all .5s ease;
transition: color 0ms;

&.is-visible {
opacity: 1;
animation: fadein 1s;
-moz-animation: fadein 1s;
-webkit-animation: fadein 1s;
-o-animation: fadein 1s;
}

svg {
filter: brightness(0) saturate(100%) invert(100%) sepia(1%) saturate(1993%) hue-rotate(169deg) brightness(99%) contrast(70%);
}

&:hover {
color: grey;
background-color: transparent;

svg {
filter: brightness(0) saturate(100%) invert(46%) sepia(9%) saturate(10%) hue-rotate(328deg) brightness(92%) contrast(85%);
}
}
}
}

--

--

--

👤 Full Stack Developer at rtCamp, Speaker, Blogger, YouTuber, Wordpress, React, Node, Laravel Developer http://youtube.com/ImranSayedDev

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

React Scroll Parallax

Async, Callbacks, & Promises

Introduction to Redux - Saga

Big O notation : Understanding different time complexities

From today i am trying to discuss about 10 days of Javascript challenge on HackerRank which is…

JSON Web Tokens With Nginx and Shibboleth

Conversation to Code (Part 2)

How to use TypeScript to develop your Node.js applications

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Imran Sayed

Imran Sayed

👤 Full Stack Developer at rtCamp, Speaker, Blogger, YouTuber, Wordpress, React, Node, Laravel Developer http://youtube.com/ImranSayedDev

More from Medium

How to Add Preloader in HTML Page?

Build a News Aggregator App using Strapi and Nuxtjs

E-commerce web app with React JS (Part 1)

How to Create a Custom Next.js Link Component With Bootstrap Icon