В этом блоге мы узнаем, как добавить прокрутку к верхней кнопке на сайте 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%); } } } }
Это все люди