Делать одностраничные сайты – модный нынче тренд. Но всегда встает вопрос написания плавной анимации по разделам сайта. Можно конечно взять jQuery и какой-никакой готовый плагин. Но не для всех страниц есть смысл подключать «массивную» библиотеку, проще написать свое решение.
Напишем наше меню:
<ul class="menu">
<li><a onclick="return app.scrollTo(this)" href="#news">Новости</a></li>
<li><a onclick="return app.scrollTo(this)" href="#about">О нас</a></li>
<li><a onclick="return app.scrollTo(this)" href="#contacts">Контакты</a></li>
</ul>
Дабы не писать метод добавления обработчика кликов по меню, я вписал вызов функции прямо в ссылку: onclick="return app.scrollTo(this)"
. Не самое лучшее, но сто процентов работающее решение.
В начале каждого раздела для любого элемента должен быть проставлен id
с соответствующим значением, например id="news"
.
var app = {
scrolled: 0,
newPosition: 0,
interval: null,
speed: 0,
scrollTo: function(el) {
var link = el.getAttribute('href').replace('#', ''),
anchor = document.getElementById(link);
var location = 0;
if (anchor.offsetParent) {
do {
location += anchor.offsetTop;
anchor = anchor.offsetParent;
} while (anchor);
}
location = location >= 0 ? location : 0;
this.animateScroll(location);
return false;
},
animateScroll: function(pos) {
document.documentElement.scrollTop = 1;
var element = (document.documentElement && document.documentElement.scrollTop) ? document.documentElement : document.body,
start = element.scrollTop,
change = pos - start,
currentTime = 0,
increment = 20,
duration = 300;
var animateScroll = function(){
currentTime += increment;
var val = Math.easeInOutQuad(currentTime, start, change, duration);
element.scrollTop = val;
if(currentTime < duration) {
setTimeout(animateScroll, increment);
}
};
animateScroll();
}
};
Функция, реализующая ускоряющуюся и замедляющуюся в конце анимацию (не моя):
Math.easeInOutQuad = function (t, b, c, d) {
t /= d/2;
if (t < 1) return c/2*t*t + b;
t--;
return -c/2 * (t*(t-2) - 1) + b;
};