WordPress как на ладони
Очень Удобный и Быстрый Хостинг для сайтов на WordPress. Пользуюсь сам и вам рекомендую!

Кнопка «Наверх» с плавным прокручиванием

Меня неоднократно просили в комментариях рассказать как реализована стрелочка «Наверх» на этом сайте. Делюсь.

Некоторые преимущества:

  • Работает во всех браузерах;
  • Пропадает вверху экрана;
  • Можно добавлять на любые сайты, не только WordPress.

Мы получим фиксировано расположенную кнопку, по нажатию на которую, экран будет передвигаться наверх плавно и стрелка будет исчезать в верху.

Ниже два варианта: на чистом JS и на jQuery. Код кнопки подойдет под любой движок, не обязательно WordPress.

Вариант 1: нативный JS

document.addEventListener( 'DOMContentLoaded', function(){

	let div = document.createElement( 'div' )
	div.innerHTML = `<button role="button" aria-label="Scroll Top" class="scroll-top-btn"></button>`.trim()
	let scrollTop = div.firstChild

	document.body.append( scrollTop )

	scrollTop.addEventListener( 'click', ev => {
		window.scrollTo( 0, 0 )
	} )

	let showHideButton = function(){
		window.scrollY > 300
			? scrollTop.classList.add( '--visible' )
			: scrollTop.classList.remove( '--visible' )
	}

	window.addEventListener( 'scroll', showHideButton )
	showHideButton()

} );

Плавное прокручивание достигается стилями:

html{
	scroll-behavior: smooth;
	scroll-padding-top: calc( var(--header-height) + 1rem );
}

Стили .scss

// scroll-top ---

.scroll-top-btn{
	font-size: 150%; // button size

	padding:0; border:0; // reset button
	display: block;
	overflow: hidden; width: 0; height: 0;
	z-index: 99; position: fixed;
	bottom: 2rem; right: 2rem;
	line-height: 0;

	border-radius: var(--border-radius);
	box-shadow: 0 3px 30px -5px rgb(0 0 0 / 30%);

	background-color: var(--white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23999' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z' clip-rule='evenodd'%3E%3C/path%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-size: 70%;
	background-position: center 50%;

	opacity: .6;
	transition: all 150ms;
	cursor:pointer;

	@include layoutBreak {
		display: none;
	}

	&.--visible { overflow: visible; width: 2em; height: 2em; }

	&:hover{
		opacity: 1;
	}
}

Вариант 1.2: нативный JS (с функцией плавного прокручивания)

document.addEventListener( 'DOMContentLoaded', function(){

	// create DOM element
	const scrollTopHTML = `<button role="button" area-lable="Scroll Top" class="scroll-top-btn"></button>`
	const div = document.createElement( 'div' )
	div.innerHTML = scrollTopHTML.trim()
	const scrollTop = div.firstChild
	document.body.append( scrollTop )

	// init

	scrollTop.addEventListener( 'click', button_click )

	window.addEventListener( 'scroll', showHideButton )
	showHideButton()

	// methods

	function button_click( ev ) {
		ev.preventDefault();

		scroll_to( {
			element: document.documentElement,
			goto: 0,
			speed: 2000,
			frames: 10,
			easing_func: 'easeOutCirc',
		} )

	}

	function showHideButton() {
		window.scrollY > 300
			? scrollTop.classList.add( '--visible' )
			: scrollTop.classList.remove( '--visible' )
	}

	function scroll_to( args ) {

		/**
		 * t = Time - Amount of time that has passed since the beginning of the animation.
		 *     Usually starts at 0 and is slowly increased using a game loop or other update function.
		 * b = Beginning value - The starting point of the animation.
		 *     Usually it's a static value, you can start at 0 for example.
		 * c = Change in value - The amount of change needed to go from starting point to end point.
		 *     It's also usually a static value.
		 * d = Duration - Amount of time the animation will take.
		 *     Usually a static value aswell.
		 *
		 * @see https://spicyyoghurt.com/tools/easing-functions
		 * @see https://easings.net/
		 */
		const easing_funcs = {

			easeLinear: ( t, b, c, d ) => {
				return c * t / d + b
			},
			easeInSine: ( t, b, c, d ) => {
				return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
			},
			easeOutSine: ( t, b, c, d ) => {
				return c * Math.sin(t / d * (Math.PI / 2)) + b;
			},
			easeInCubic: ( t, b, c, d ) => {
				return c * (t /= d) * t * t + b;
			},
			easeOutCubic: ( t, b, c, d ) => {
				return -c * (t /= d) * (t - 2) + b
			},
			easeInExpo: ( t, b, c, d ) => {
				return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
			},
			easeOutExpo: ( t, b, c, d ) => {
				return ( t === d ) ? b + c : c * ( -Math.pow( 2, -10 * t / d ) + 1 ) + b
			},
			easeOutCirc: ( t, b, c, d ) => {
				return c * Math.sqrt(1 - (t = t / d - 1) * t) + b
			},

		}

		const el = args.element || document.documentElement
		const speed = args.speed
		const frames = args.frames || 10
		const goto_pos = args.goto
		const easing_func = args.easing_func || 'easeLinear'
		const anim_end_func = args.anim_end || null
		const anim_start_func = args.anim_start || null

		const start_pos = el.scrollTop
		const start_time = Date.now()
		let tuntime_frames = Math.round( speed / frames )

		const recursive = () => {

			let left_time = ( Date.now() - start_time )
			let anim_tick = left_time / tuntime_frames--
			let anim_step = Math.min( left_time / speed, 1 ) // max 1

			el.scrollTop = easing_funcs[ easing_func ]( anim_step, start_pos, (goto_pos - start_pos), 1 )

			if( anim_step !== 1 ){
				// next anim step
				this._scroll_to_tick_tm = setTimeout( recursive, anim_tick )
			}
			// done
			else {
				delete this._scroll_to_tick_tm
				// add a delay for sure
				anim_end_func ? setTimeout( anim_end_func, 20 ) : null
			}

		}

		// RUN if already not in process
		if( ! this._scroll_to_tick_tm ){

			anim_start_func && anim_start_func()

			recursive()
		}

	}

} );

Стили для кнопки возьмите из примера 1.

Вариант 2: Кнопки «Наверх» на чистом JavaScript

Посмотреть ДЕМО на чистом javascript >>>

Если на сайте нет jQuery, то нет смысла подключать достаточно объемный фреймворк, только для того, чтобы установить такую кнопку.

Для того, чтобы реализовать такую, плавно прокручивающуюся кнопку "наверх" без jQuery используйте такой js код:

/**
 * Scrolling script: scrollTop button
 * button css class: scrollTop
 */

window.top = {};
var sc = window.top;

sc.time = 12; // cranking time

sc.goTop = function (time, acceleration) {
	acceleration = acceleration || 0.1;
	time = time || sc.time;

	var dx = 0;
	var dy = 0;
	var bx = 0;
	var by = 0;
	var wx = 0;
	var wy = 0;

	if (document.documentElement) {
		dx = document.documentElement.scrollLeft || 0;
		dy = document.documentElement.scrollTop || 0;
	}
	if (document.body) {
		bx = document.body.scrollLeft || 0;
		by = document.body.scrollTop || 0;
	}
	var wx = window.scrollX || 0;
	var wy = window.scrollY || 0;

	var x = Math.max(wx, Math.max(bx, dx));
	var y = Math.max(wy, Math.max(by, dy));

	var speed = 1 + acceleration;
	window.scrollTo(Math.floor(x / speed), Math.floor(y / speed));
	if(x > 0 || y > 0) {
		var invokeFunction = "window.top.goTop("+ time +")"
		window.setTimeout(invokeFunction, time);
	}
	return false;
}

sc.showHide = function (){
	var a = document.getElementById('gotop');

	if( ! a ){
		// If there is no item, add it
		var a = document.createElement('a');
		a.id = "gotop";
		a.className = "scrollTop";
		a.href = "#";
		a.style.display = "none";
		a.style.position = "fixed";
		a.style.zIndex = "9999";
		a.onclick = function(e){ e.preventDefault(); window.top.goTop(); }
		document.body.appendChild(a);
	}

	var stop = (document.body.scrollTop || document.documentElement.scrollTop);
	if( stop > 300 ){
		a.style.display = 'block';
		sc.smoothopaque(a, 'show', 30, false);
	} else {
		sc.smoothopaque(a, 'hide', 30, function(){a.style.display = 'none';});
	}

	return false;
}

// Smooth change of transparency
sc.smoothopaque = function (el, todo, speed, endFunc){
	var
	startop = Math.round( el.style.opacity * 100 ),
	op = startop,
	endop = (todo == 'show') ? 100 : 0;

	clearTimeout( window['top'].timeout );

	window['top'].timeout = setTimeout(slowopacity, 30);

	function slowopacity(){
		if( startop < endop ){
			op += 5;
			if( op < endop )
				window['top'].timeout = setTimeout(slowopacity, speed);
			else
				(endFunc) && endFunc();
		}
		else {
			op -= 5;
			if( op > endop ){
				window['top'].timeout = setTimeout(slowopacity, speed);
			}
			else
				(endFunc) && endFunc();
		}

		// opacity
		el.style.opacity = (op/100);
		el.style.filter = 'alpha(opacity=' + op + ')';
	}
}

if (window.addEventListener){
	window.addEventListener("scroll", sc.showHide, false);
	window.addEventListener("load", sc.showHide, false);
}
else if (window.attachEvent){
	window.attachEvent("onscroll", sc.showHide);
	window.attachEvent("onload", sc.showHide);
}

CSS стили нужно указать отдельно в файле стилей:

.scrollTop{
	background:url('путь_до_файла.png') 0 0 no-repeat;
	width:50px; height:70px;
	bottom:10px; left:48%;
}
.scrollTop:hover{ background-position:0 -76px; }

Вариант 3: Кнопки «наверх» на jQuery

ДЕМО: посмотреть как это выглядит >>>

1. Подключим jQuery

Для начала нам нужно подключить jQuery, если он еще не установлен на вашем сайте (такое бывает редко). Для этого скопируйте следующий код в файл темы functions.php:

add_action('wp_enqueue_scripts', 'my_scripts_method' );
function my_scripts_method(){
	wp_enqueue_script( 'jquery' );
}

Если jQuery у вас уже подключен, то этот пункт можно пропустить.

2. Встроим .js код

Следующим шагом встроим код самой кнопки. Для этого создадим файл my_topbutton.js и вставим в него код ниже. Затем нужно этот файл подключить на страницу.

Или чтобы не возиться с файлом, можно просто скопировав этот код в какой-нибудь уже имеющийся .js файл.

Этот код должен подключаться после кода jQuery библиотеки.

jQuery(document).ready(function($){

	/**
	 * Кнопка наверх на jQuery.
	 * Автор: Тимур Камаев - wp-kama.ru
	 * version 2.2
	 */
	$('body').append('<style>\
		.scrollTop{\
			display:none; z-index:9999; position:fixed; bottom:10px; left:48%; width:50px; height:70px;\
			background:url(http://example.com/путь_до_файла.png) 0 0 no-repeat;\
		}\
		.scrollTop:hover{ background-position:0 -76px;}\
	</style>');

	var speed      = 500,
		$scrollTop = $('<a href="#" class="scrollTop"></a>').appendTo('body');

	$scrollTop.click(function(e){
		e.preventDefault();

		$( 'html:not(:animated),body:not(:animated)' ).animate({ scrollTop: 0}, speed );
	});

	// появление
	function show_scrollTop(){
		( $(window).scrollTop() > 300 ) ? $scrollTop.stop().fadeIn(600) : $scrollTop.stop().fadeOut(600);
	}
	$(window).scroll( function(){ show_scrollTop(); } );
	show_scrollTop();

});
3. Настроим CSS стили

Во вставленном JS коде есть строки со CSS стилями:

$('body').append('<style>\
	.scrollTop{\
		display:none; z-index:9999; position:fixed; bottom:10px; left:48%; width:50px; height:70px;\
		background:url(http://example.com/путь_до_файла.png) 0 0 no-repeat;\
	}\
	.scrollTop:hover{ background-position:0 -76px;}\
</style>');

Вместо http://example.com/путь_до_файла.png нужно указать путь до файла-картинки с изображением стрелок. Картинку нужно залить на сайт.

Также нужно изменить размеры под картинку: width:50px; height:70px; и background-position:0 -76px;. Эти размеры рассчитаны на картинку 50х140 пикселей:

arrows1

Если у вас другая картинка, то в параметре width:50px; укажите ширину картинки; в параметре height:70px; укажите половину высоты (высоту верхней части картинки); в параметре background-position:0 -76px; - на сколько пикселей отступить от верха картинки при наведении мыши на "кнопку". Для этой картинки -76px.

Все, готово!

Так, в три шага можно установить кнопку "наверх", при нажатии на которую пользователя будет плавно перекидывать в начало страницы.

#3.2 CSS стили без использования картинки - все еще проще!

В силу последних тенденций простоты, можно вообще не использовать картинку, и просто настроить кнопку через css стили, вот пример:

$('body').append('<style>\
	.scrollTop{\
		display:none; z-index:9999; position:fixed; bottom:0; padding:1em 2em; left:48%; border-radius:.2em;\
		background:rgba(0,0,0,0.2); color:#fff;\
	}\
	.scrollTop:hover{ background:rgba(0,0,0,0.6); color:#fff; text-decoration:none; }\
	.scrollTop:before{ content:"▴"; /* ▲ ▴ △ ▵ ⏫ ⏶ ⧋ */ }\
</style>');

Замените аналогичные строки в код скрипта на эти и у вас получиться такая кнопка:

naverh-knopka-dlya-sajta

Картинки для кнопок (для вариантов 2 и 3)

Посидел, набрал несколько картинок, которые возможно вам понравятся.

arrows1 arrows15 arrows18 arrows14 arrows12 arrows7 arrows13 arrows3 arrows4 arrows6 arrows5 arrows17 arrows8 arrows10 arrows11 arrows16 arrows2 arrows9

Копируйте картинку к себе на сайт и затем измените CSS стили под скопированную картинку, вот так:

.scrollTop{
	background:url('путь_до_файла.png') 0 0 no-repeat;
	width:50px; /* изменяем: ширина картинки */
	height:70px; /* изменяем: высота кнопки - половина высоты картинки */
	bottom:10px;
	left:48%;
}
.scrollTop:hover{
	/* изменяем: отступ при наведении,
	нужно подбирать вручную. Примерно равен высоте кнопки */
	background-position:0 -76px;
}
210 комментариев
Полезные 6 Все
    Войти