
Горизонтальный скроллер на JavaScript
Захотел сделать горизонтальный скроллер для фотогалереи, естественно, без использования всяких сторонних скриптов. Условие: кроссбраузерность, валидная верстка и стандартные стили, поддержка колесика мыши. Начнем с верстки:
<div class="scroller_container">
<div class="scroller_navigate"><img src="images/left.gif" alt=""></div>
<div class="scroller_window" id="scroller_window">
<div class="scroller_row" id="scroller_row">
<div id="scroller_rule">
<!-- список превьюшек в линейке скроллера -->
<a href="#"><img src="..." width="150" height="100" alt=""></a>
<a href="#"><img src="..." width="150" height="100" alt=""></a>
<a href="#"><img src="..." width="150" height="100" alt=""></a>
<a href="#"><img src="..." width="150" height="100" alt=""></a>
</div>
</div>
</div>
<div class="scroller_navigate"><img src="images/right.gif" alt=""></div>
</div>
Дополнительный элемент
scroller_rule приходится использовать, чтобы получить полную ширину всей полосы скроллера с превьюшками. Элементы
scroller_navigate содержат левую и правую стрелочки для прокрутки. Теперь надо создать таблицу стилей для оформления. "Окно" скроллера должно быть фиксированного размера и без полос прокрутки, а полоса скроллера будет перемещаться относительно этого окна, за счет этого будет достигаться эффект плавной прокрутки. Для большей красоты я взял фоновый рисунок, имитирующий фотопленку.
<style type="text/css">
.scroller_container div {
float: left;
vertical-align: baseline;
}
.scroller_window {
width: 850px; /* ширина окна скроллера */
overflow: hidden;
}
.scroller_row {
position: relative;
white-space: nowrap;
width: 100%;
padding: 22px 0 22px 0; /* отступы для перфорации пленки */
background: url('images/foto.gif') repeat-x;
}
.scroller_row img {
padding: 0px;
margin: 0px;
}
.scroller_row a {
padding: 0px;
margin: 0px;
}
.scroller_navigate {
padding: 2px 1px 0 1px;
cursor: pointer;
}
a img {
border: 0px;
}
</style>
Наш скроллер уже выглядит симпатично, теперь надо добавить анимацию. Здесь используются уже описанные ранее функции определения браузера и функции работы с колесиком мыши, их особенности и назначение описаны в соответствующих статьях. Небольшой комментарий по поводу корректировки размеров элемента
scroller_row. Как выяснилось на практике, браузеры Opera и Chrome отображают фоновый рисунок только для видимой части полосы скроллера, поэтому приходится принудительно устанавливать стиль width полосе скроллера, чтобы фоновый рисунок растянулся на всю его ширину.
// Глобальный объект скроллера
var scroller={ };
// Инициализация скроллера
function scroller_init() {
var el;
// Получить ширину внутренней части скроллера
el=document.getElementById('scroller_rule');
scroller.width=el.clientWidth;
// Получить ширину окна скроллера
el=document.getElementById('scroller_window');
scroller.window=el.clientWidth;
// Установка обработчика колесика мыши
if (el.addEventListener) {
// Mozilla, Opera, Safari, Chrome
if (!(smart_chrome_check()=='666' || typeof(opera)=='object')) {
el.addEventListener('DOMMouseScroll', scroll_wheel, false);
}
else {
el.addEventListener('mousewheel', scroll_wheel, false);
}
}
else {
// IE
el.attachEvent('onmousewheel', scroll_wheel);
}
scroller.position=0;
scroller.step=2;
scroller.timer=null;
// fix размеров для background (Opera, Chrome)
el=document.getElementById('scroller_row');
el.style.width=scroller.width;
}
// Проверка на Google Chrome
function smart_chrome_check() {
// 66 - Internet Explorer && Chrome Trap
return(arguments.callee.toString().replace(/[^6]/g,''));
}
// Обработчик колесика мыши
function scroll_wheel(e) {
e = e ? e : window.event;
var wheelElem = e.target ? e.target : e.srcElement;
var wheelData = e.detail ? e.detail * -1 : e.wheelDelta / 40;
// В движке WebKit возвращается значение в 100 раз больше
if (Math.abs(wheelData)>100) { wheelData=Math.round(wheelData/100); }
if (wheelData<0) {
do_scroll('right',10*Math.abs(wheelData));
}
else {
do_scroll('left',10*Math.abs(wheelData));
}
// Подавление события колесика мыши, чтобы оно не передавалось дальше
if (window.event) {
e.cancelBubble = true;
e.returnValue = false;
e.cancel = true;
}
if (e.stopPropagation && e.preventDefault) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
// Функция скроллера
function do_scroll(dir,step) {
var el=document.getElementById('scroller_row');
// Прокрутка влево
if (dir=='left') {
scroller.position+=step;
// Если скроллер вышел за левую границу, то установить позицию в 0
if (scroller.position>0) {
scroller.position=0;
}
}
// Прокрутка вправо
else {
scroller.position-=step;
// Если скроллер вышел за правую границу, то установить позицию в край
if (scroller.position<(scroller.window-scroller.width)) {
scroller.position=scroller.window-scroller.width;
}
}
// Установить позицию полосы скроллера
el.style.left=scroller.position+'px';
}
// Таймер скроллера
function scroll_timer(dir) {
if (scroller.timer==null) {
scroller.timer=setInterval("do_scroll('"+dir+"', "+scroller.step+");",10);
}
}
// Остановка скроллера
function scroll_stop() {
if (scroller.timer!=null) {
clearInterval(scroller.timer);
scroller.timer=null;
}
}
На боковые элементы навигации
scroller_navigate устанавливаются обработчики движения мыши на функции
scroll_timer и
scroll_stop:
<div class="scroller_navigate"><img src="images/left.gif" alt=""
onmousemove="scroll_timer('left');" onmouseout="scroll_stop();"></div>
...
<div class="scroller_navigate"><img src="images/right.gif" alt=""
onmousemove="scroll_timer('right');" onmouseout="scroll_stop();"></div>
Также после загрузки страницы надо обязательно инициализировать наш скроллер:
<script type="text/javascript">scroller_init();</script>
Теперь, если на них навести мышку, то скроллер будет прокручиваться в нужную сторону. При прокрутке колесиком мыши над "окном" скроллера, он также будет прокручиваться влево или вправо. Обработчиков действий при клике на фотографии здесь не предусмотрено, они будут разрабатываться в зависимости от конкретной задачи.