В этом блоге мы узнаем, как добавить прокрутку к верхней кнопке на сайте WordPress.

Кнопка прокрутки вверх

Добавьте кнопку прокрутки вверх в footer.php Обратите внимание, что некоторые из классов, которые я использую, взяты из tailwindcss

<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>

Инвиевпортанимация

Создайте файл JS с именем in-viewport-animation.js .

$ = 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();
   }
}

Функция отката

Создайте файл JS с именем functions.js

/**
 * 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 );
   };
   
};

Прокрутите вверх основной файл JS

Создайте еще один файл с именем scroll-to-top.js

/**
 * 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 );

Прокрутить вверх 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%);
         }
      }
   }
}

Это все люди