Дополнительные модификации кнопки «Наверх»

Это статья — продолжение к моему старому посту про кнопку наверх, который с момента публикации набрал максимальное количество просмотров среди остальных постов на блоге и 95 комментариев!

Вот скрин из Google Analytics, топ 3 поста на блоге с момента публикации «кнопки наверх»:

кнопка наверх в Google Analytics

Отрыв практически в два раза, впечатляет 🙂

В комментах меня просили, и не раз, сделать точную копию кнопки как вконтакте, то есть чтобы при прокрутке наверх она превращалась в кнопку «Назад» (это было в то время), а сейчас там кнопка немного поменялась и теперь её можно назвать кнопкой «Вверх-вниз» (возвращает обратно в ту часть страницы, откуда вы нажали «наверх». Сегодня я распишу оба варианта.

1. Кнопка «Наверх-Назад» (на предыдущую страницу)

Теория этой кнопки в том, что когда человек нажал на кнопку «наверх», ему захочется вернуться на предыдущую просмотренную страницу (разве что предыдущая страница — результаты поиска в Google) и поэтому ему необходимо предложить такую возможность.

HTML

Сначала HTML-код, вставьте его куда-нибудь на своё усмотрение, я бы засунул перед закрывающим тегом </body>:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="button_back.js"></script>
<div id="top-link">
	<a href="#top">наверх</a>
</div>

Повторю ещё раз, если кнопка не работает, попробуйте при подключении файла button_back.js прописать абсолютный URL.

CSS

#top-link{
	cursor:pointer;
	display:none;
	position:fixed;
	top:0px;
	bottom:0px;
	padding-left:5px;
	padding-top:5px;
	z-index:1;
}
#top-link a{
	display:block;
}

jQuery

Это содержимое файла button_back.js. Обратите внимание на ID основного блока с контентом на 3-й строчке кода, у меня это #content, а у вас может быть что-нибудь другое, например #wrapper или #container.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
jQuery.extend(jQuery.fn, {
	toplinkwidth: function(){
		totalContentWidth = jQuery('#content').outerWidth(); // ширина блока с контентом, включая padding
		totalTopLinkWidth = jQuery('#top-link').children('a').outerWidth(true); // ширина самой кнопки наверх, включая padding и margin
		h = jQuery(window).width()/2-totalContentWidth/2-totalTopLinkWidth;
		if(h<0){
			// если кнопка не умещается, скрываем её
			jQuery(this).hide();
		} else {
			if(jQuery(window).scrollTop() >= 1){
				jQuery(this).show();
			}
			jQuery(this).css({'padding-right': h+'px'});
		}
	}
});
 
jQuery(function($){
	var topLink = $('#top-link');
	topLink.css({'padding-bottom': $(window).height()});
	// если вам не нужно, чтобы кнопка подстраивалась под ширину экрана - удалите следующие четыре строчки в коде
	topLink.toplinkwidth();
	$(window).resize(function(){
		topLink.toplinkwidth();
	});
	$(window).scroll(function() {
		if($(window).scrollTop() >= 1) {
			topLink.fadeIn(300).children('a').html('наверх').parent().removeAttr("onClick");
		} else {
			topLink.children('a').html('назад').parent().attr("onClick", "history.back()");
		}
	});
	topLink.click(function(e) {
		$("body,html").animate({scrollTop: 0}, 500);
		return false;
	});
});

P.S. в примере я особо не заморачивался с оформлением кнопки — всё только самое необходимое, если вам нужно оформление — смотрите или скачивайте демо.

2. Кнопка «Наверх-Вниз» (обратно в ту часть страницы, где был переход наверх)

Как я уже говорил, вконтакте отказались от теории, по которой посетителю постоянно хочется перейти на предыдущую просмотренную страницу.

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

Подробнее о том, как определить текущее местонахождение на странице.

Итак, погнали.

HTML и CSS

Тут практически всё точно также, как и в предыдущем примере (но в демо есть некоторые отличия в CSS), единственное только я назвал по-другому файл со скриптами, button_down.js:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="button_down.js"></script>
<div id="top-link">
	<a href="#top">наверх</a>
</div>
#top-link{
	cursor:pointer;
	display:none;
	position:fixed;
	top:0px;
	bottom:0px;
	padding-left:5px;
	padding-top:5px;
	z-index:1;
}
#top-link a{
	display:block;
}

jQuery + плагин scrollTo

Содержимое файла button_down.js, опять-таки не забывает изменить ID элемента #content.

;(function($){var h=$.scrollTo=function(a,b,c){$(window).scrollTo(a,b,c)};h.defaults={axis:'xy',duration:parseFloat($.fn.jquery)>=1.3?0:1,limit:true};h.window=function(a){return $(window)._scrollable()};$.fn._scrollable=function(){return this.map(function(){var a=this,isWin=!a.nodeName||$.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!isWin)return a;var b=(a.contentWindow||a).document||a.ownerDocument||a;return/webkit/i.test(navigator.userAgent)||b.compatMode=='BackCompat'?b.body:b.documentElement})};$.fn.scrollTo=function(e,f,g){if(typeof f=='object'){g=f;f=0}if(typeof g=='function')g={onAfter:g};if(e=='max')e=9e9;g=$.extend({},h.defaults,g);f=f||g.duration;g.queue=g.queue&&g.axis.length>1;if(g.queue)f/=2;g.offset=both(g.offset);g.over=both(g.over);return this._scrollable().each(function(){if(e==null)return;var d=this,$elem=$(d),targ=e,toff,attr={},win=$elem.is('html,body');switch(typeof targ){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ)){targ=both(targ);break}targ=$(targ,this);if(!targ.length)return;case'object':if(targ.is||targ.style)toff=(targ=$(targ)).offset()}$.each(g.axis.split(''),function(i,a){var b=a=='x'?'Left':'Top',pos=b.toLowerCase(),key='scroll'+b,old=d[key],max=h.max(d,a);if(toff){attr[key]=toff[pos]+(win?0:old-$elem.offset()[pos]);if(g.margin){attr[key]-=parseInt(targ.css('margin'+b))||0;attr[key]-=parseInt(targ.css('border'+b+'Width'))||0}attr[key]+=g.offset[pos]||0;if(g.over[pos])attr[key]+=targ[a=='x'?'width':'height']()*g.over[pos]}else{var c=targ[pos];attr[key]=c.slice&&c.slice(-1)=='%'?parseFloat(c)/100*max:c}if(g.limit&&/^\d+$/.test(attr[key]))attr[key]=attr[key]<=0?0:Math.min(attr[key],max);if(!i&&g.queue){if(old!=attr[key])animate(g.onAfterFirst);delete attr[key]}});animate(g.onAfter);function animate(a){$elem.animate(attr,f,g.easing,a&&function(){a.call(this,e,g)})}}).end()};h.max=function(a,b){var c=b=='x'?'Width':'Height',scroll='scroll'+c;if(!$(a).is('html,body'))return a[scroll]-$(a)[c.toLowerCase()]();var d='client'+c,html=a.ownerDocument.documentElement,body=a.ownerDocument.body;return Math.max(html[scroll],body[scroll])-Math.min(html[d],body[d])};function both(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
 
jQuery.extend(jQuery.fn, {
	toplinkwidth: function(){
		totalContentWidth = jQuery('#content').outerWidth(); // ширина блока с контентом, включая padding
		totalTopLinkWidth = jQuery('#top-link').children('a').outerWidth(true); // ширина самой кнопки наверх, включая padding и margin
		h = jQuery(window).width()/2-totalContentWidth/2-totalTopLinkWidth;
		if(h<0){
			// если кнопка не умещается, скрываем её
			jQuery(this).hide();
		} else {
			if(jQuery(window).scrollTop() >= 1){
				jQuery(this).show();
			}
			jQuery(this).css({'padding-right': h+'px'});
		}
	}
});
 
jQuery(function($){
	var topLink = $('#top-link');
	topLink.css({'padding-bottom': $(window).height()});
	// если вам не нужно, чтобы кнопка подстраивалась под ширину экрана - удалите следующие четыре строчки в коде
	topLink.toplinkwidth();
	$(window).resize(function(){
		topLink.toplinkwidth();
	});
	$(window).scroll(function() {
		if($(window).scrollTop() >= 1) {
			topLink.fadeIn(300).children('a').html('наверх').parent().removeClass('bottom_button').addClass('top_button');
		} else {
			topLink.children('a').html('вниз').parent().removeClass('top_button').addClass('bottom_button');
		}
	});
	topLink.click(function(e) {
		if($(this).hasClass('bottom_button')){
			// при нажатии на кнопку «Вниз» переходим туда, где прекратили чтение
			$("body").scrollTo( pos + 'px', 500 );
		} else{
			// определяем и запоминаем координаты того места страницы, откуда был совершен переход наверх
			pos = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
			$("body,html").animate({scrollTop: 0},500);
		}
		return false;
	});
});

Работоспособность кода протестирована в браузерах Google Chrome, Mozilla Firefox и Opera (в актуальных на момент обновления данной статьи версиях).

Миша Рудрастых Разработчик WordPress WooCommerce

Миша Рудрастых

Впервые познакомился с WordPress в 2009 году, и после двух лет мучений с Joomla и самописными движками это был просто бальзам на душу. С 2014 года меня можно встретить на WordCamp — официальной конфе по WP в Москве, иногда там выступаю. Также в настоящее время веду курсы по WordPress в Epic Skills в Питере.

Смотрите также