Вообще-то для этого существует комбинация клавиш Ctrl + Home — в самый вверх, и Ctrl + End — в самый низ, если кто не знает или не помнит. Но ещё бывает лень потянуться к клавиатуре чтобы нащупать соответстующие кнопки, особенно когда сидишь откинувшись в кресле, а в руках чашка с кофе. Что касается обычных, в том числе «непродвинутых» юзеров, так им и дела нет до каких-то сочетаний и комбинаций.
По всей видимости, чтобы облегчить жизнь людям, сберечь их время и силы придумали такие интерфейсные элементы. На многих сайтах сейчас можно встретить кнопку «наверх» в самых разных местах страницы, её лепят куда угодно, как правило, в один из углов страницы.
Единого стандарта нет, и быть не может, но давайте всё-таки обозначим несколько основных требований:
- Кнопка хорошо заметна, в то же время не «мозолит» глаза.
- В неё удобно попадать мышкой, не особо целясь.
- Появляется тогда, когда это необходимо.
- Имеет единое местоположение на всех страницах.
- По возможности имеет возможность скрытия.
На мой взгляд, удачно сделано на vk.com и здесь, на Хабре. Сабж представляет из себя появляющуюся при наведении курсора боковую панель. По клику в любой области можно переместиться в топ, и вернуться обратно, в то место откуда прокрутил наверх. Когда привыкаешь ей пользоваться, то замечаешь, что на других сайтах этой штуки не хватает.
Теперь я расскажу как воспроизвёл данный функционал с помощью фреймворка Prototype.js. Для тех, кто не знаком: удобство этой библиотеки в том, что она позволяет программировать на javascript в стиле классического ООП. Конечно, условно, так как там много чего нет, например private методов и свойств, зато можно реализовать наследование или объявить статические переменные класса.
Нам понадобится еще одна библиотека, которая будет работать в паре с Prototype — script.aculo.us, она будет выполнять «хитрый» скролл.
Особенности нашей кнопки:
- Будет появляться постепенно, по мере прокрутки. С того момента, как будет откручено min пикселей кнопка начнет появляться, и на max станет полностью непрозрачной (будет изменяться свoйство css opacity). Соответственно, в направлении вверх, будет плавно исчезать.
- Страница НЕ будет прокручиваться от начала и до конца, мелькая всем содержимым перед глазами. Вместо этого перескочит, и затем плавно пройдёт пару десятков пикселей (brakingDistance) к установленному месту, чтобы было интуитивно понятно в каком направлении выполняется прокрутка.
Далее, код html, css и javascript. Полагаю, там всё предельно понятно, небольшие комментарии внутри.
<div class="toTop" id="toTop">
<div class="toTopPanel" id="ttPanel">
<img src="images/scrollTop.gif" width="40" height="40" class="toTopButton" id="ttButton">
<img src="images/scrollBack.gif" width="40" height="40" class="toTopBack" id="ttBackButton">
</div>
</div>
.toTop {
bottom: 0;
display: none;
left: 0;
display:block;
position: fixed;
top: 0;
width: 40px;
height: 100%;
opacity:0.5;
}
.toTop:hover {
opacity:1;
}
.toTop .toTopPanel {
height: 100%;
background:transparent;
cursor: pointer;
}
.toTop .toTopPanel:hover {
background: none repeat scroll 0 0 #dfdfcc;
}
.toTop .toTopButton, .toTop .toTopBack {
position: absolute;
top:50%;
}
var toTop = Class.create();
toTop.prototype = {
initialize: function(params) {
// значения по умолчанию
this.min = 200;
this.max = 600;
this.brakingDistance = 20;
this.scrollDuration = '0.1';
// поехали
Object.extend(this, params);
var that = this;
this.holder = $(this.holder);
this.lastPosition = false;
['ttPanel', 'ttButton', 'ttBackButton'].each(function(name) {
that[name] = that.getById(name);
});
this.ttPanel.observe('click', this.scroll.bindAsEventListener(this));
this.panelBehavior();
Event.observe(window, 'scroll', this.panelBehavior.bindAsEventListener(this));
// шаман-маман
this.ttPanel.observe('mouseover', function(){
that.ttButton.setStyle({opacity:''});
that.over = true;
});
this.ttPanel.observe('mouseout', function(){
that.panelBehavior();
that.over = false;
});
},
// получить элемент по id внутри holder
getById: function(name) {
return (el = this.holder.select('[id="'+name+'"]')) ? el[0] : false;
},
// упаравление поведением панели
panelBehavior: function () {
var scrOffst = document.viewport.getScrollOffsets(),
top = scrOffst.top,
bb = this.ttBackButton,
tb = this.ttButton;
if (top < this.min) {
if (this.lastPosition) {
bb.show();
tb.hide();
} else
this.ttPanel.hide();
return;
}
this.lastPosition = false;
bb.hide();
tb.show();
if ((top < this.max) && !this.over)
tb.setOpacity((1 - (this.max - top)/(this.max - this.min)));
else
tb.setStyle({opacity:''});
this.ttPanel.show();
},
// прокрутка вверх/вниз
scroll: function() {
var scrOffst = document.viewport.getScrollOffsets(),
top = scrOffst.top,
body = $$('body')[0],
st = Effect.ScrollTo,
dr = this.scrollDuration,
lp = this.lastPosition,
bd = this.brakingDistance;
// скролл с "доводкой"
if ((top < this.min) && this.lastPosition) {
st(body, {duration:0, offset: (lp - bd), afterFinish:function(){
st(body, {duration:dr, offset: lp});
}});
} else {
st(body, {duration:0, offset:bd, afterFinish:function(){
st(body, {duration:dr});
}});
this.lastPosition = top;
}
}
};
Примеры вызова:
new toTop({
holder: 'toTop'
});
new toTop({
holder: 'toTop',
min: 300,
max: 800,
brakingDistance: 50;
});
Посмотреть как всё это выглядит можно здесь: zavtraka.net
Документацию по Prototype.js можно почитать здесь: api.prototypejs.org
Скачать последние версии библиотек: prototypejs.org/download/, script.aculo.us/downloads
Автор: ekokh