Главная → Техноблог → Делаем слайд-шоу с использованием jQuery
Делаем слайд-шоу с использованием jQuery
Июнь, 29. 2011 годТехнология Flash все реже и реже используется для интерактивных элементов web-страниц. Это происходит благодаря развитию технологии CSS и появлению различных JS библиотек. Одной из таких библиотек является jQuery. Ее функционал позволяет легко получать доступ к любому элементу DOM, обращаться к атрибутам и содержимому элементов DOM, манипулировать ими. Рассмотрим использование некоторых функций jQuery на примере создания слайд-шоу.
Но прежде чем писать скрипты, давайте сначала определимся со структурой нашего слайд-шоу и опишем ее с помощью HTML.

Как мы видим на рисунке, наше слайдшоу представляет собой выстроенные в один ряд изображения и стрелки прокрутки. Опишем данную структуру следующим HTML кодом:
<div id="gallery"> <div class="container"> <ul> <li><img src="img/img01.jpg" /></li> <li><img src="img/img02.jpg" /></li> <li><img src="img/img03.jpg" /></li> <li><img src="img/img04.jpg" /></li> </ul> </div> <div class="nav prev"><a href="#" title="назад">назад</a></div> <div class="nav next"><a href="#" title="вперед">вперед</a></div> </div>
Здесь роль стрелок навигации у нас будут выполнять ссылки «назад» и «вперед», а списком изображений будет служить список, расположенный в блоке с классом container.
Теперь перейдем к описанию CSS. Так как блок нашего слайд-шоу должен быть по ширине резиновым, присваиваем всем блокам, лежащим внутри внешнего блока gallery свойство float: left, тем самым выстраивая их в один ряд. Затем блок с изображениями делаем на всю ширину родительского блока, стрелку «назад» отодвигаем влево на величину ширины родительского блока, а стрелку «вперед» отодвигаем влево на свою ширину. Ширина стрелок навигации у нас будет равна 40 px. Для того чтобы лучше понять наши манипуляции взгляните на рисунок.

Теперь займемся списком с изображениями. Наша задача расположить их в ряд, но так чтобы он не переносился на другую строку, если его длина будет больше чем длина родительского блока. Для этого присвоим списку свойства white-space: nowrap и overflow: hidden. Первое запретит перенос дочерних элементов на следующую строку, а второе скроет элементы, выходящие за ширину списка. Элементам списка присвоим, в свою очередь свойства display: inline тем самым разместив их в горизонтальный ряд подобно обычному тексту.
Настала очередь заняться стилизацией стрелок навигации. Делаем их размеры такие же, как и родительский блок и скрываем текст внутри них. Открываем любой графический редактор и делаем изображения стрелок «назад» и «вперед». У меня получились вот такие:
![]()
После всех манипуляций у нас получается следующий код CSS:
#gallery div.container { width: 100%; float: left; overflow: hidden; } #gallery ul { overflow:hidden; list-style:none; margin:0; padding:0; white-space:nowrap; width:100%; } #gallery ul li { display:inline; } #gallery div.nav { float:left; height:150px; width:40px; } #gallery div.prev { margin-left: -100%; } #gallery div.next { margin-left: -40px; } #gallery div.nav a { display:block; width:100%; height:100%; overflow:hidden; text-indent:-1000px; opacity:0.5; filter: alpha(opacity = 50); } #gallery div.prev a { background:url(prev.png) no-repeat center center #eee; } #gallery div.next a { background:url(next.png) no-repeat center center #eee; } #gallery div.nav a:hover { opacity:0.7; filter: alpha(opacity = 70); }
Обратите внимание на то, что в описании стиля ссылок есть два свойства: opacity и filter. Задача у них двоих одинаковая: задать прозрачность элементу. Второй параметр необходим корректного отображения в браузере IE, т.к. свойство opacity он не понимает.
Если вы в коде HTML делали пункты списка с изображениями делали каждый на отдельной строке, то вы могли заметить что между изображениями есть пробелы. Их наличие обусловлено тем, что элементы списка воспринимаются как строчные элементы, а переход на новую строку воспринимается как пробел. От этих пробелов можно 2-мя способами:
- С помощью CSS-свойства word-spacing, присвоив ему отрицательную ширину пробельного символа. Недостаток этого способа состоит в том, что у каждого размера и типа шрифта эта величина разная и вам нужно будет экспериментально каждый раз подбирать ее.
- Убрать лишние символы между элементами списка: вручную или с помощью JS. Данный метод является более предпочтительным, тем более недостатков у него я не вижу.
Итак, структура слайд-шоу готова, осталось только заставить ее двигаться. Суть пролистывания изображений заключается в динамическом изменении CSS-свойства text-indent у списка, в котором они находятся. Задавая свойству положительное значение, мы сдвигаем дочерние элементы вправо, отрицательное значение — влево. Для того чтобы прокрутить весь список до конца его нужно сместить влево на разницу значений ширины этого списка элементов и ширины родительского элемента. Эти величины можно получить из DOM свойств объекта. Свойство scrollWidth определяет ширину списка элементов в объекте, а clientWidth — ширину самого объекта.

Разностью этих величин у нас будет параметр width:
var width = $("#gallery ul").attr("scrollWidth") - $("#gallery ul").attr("clientWidth");
Для динамического изменения свойства text-indent нам идеально подходит функция jQuery animate (). Она позволяет осуществлять анимацию списка CSS-свойств за заданный промежуток времени. Полное описание с примерами можно прочитать на сайте jQuery. Какое CSS-свойство изменять, мы уже определили, осталось разобраться со временем, за которое будет происходить анимация – для этого заведем переменную elapsed. Чтобы каждый раз не подбирать необходимое время для прокрутки всех изображений просто возьмем ширину списка элементов и умножим на некий коэффициент – переменная factor. Чем больше значение коэффициента – тем медленней будет осуществляться прокрутка.
var factor = 2.5; var elapsed = width * factor;
Для того чтобы привязать анимацию к стрелкам навигации возьмем методы mouseenter или mousedown. Первый срабатывает при наведении курсора мыши на объект, второй – при нажатии кнопкой мыши на объект. Получаем следующий код:
$("#gallery .prev").mouseenter ( function () { $("#gallery ul").stop(true); indent = - parseInt ( $("#gallery ul").css("text-indent") ); $("#gallery ul").animate({ textIndent: 0}, elapsed - ( width - indent ) * factor ); }); $("#gallery .next").mouseenter ( function () { $("#gallery ul").stop(true); indent = - parseInt ( $("#gallery ul").css("text-indent") ); $("#gallery ul").animate({ textIndent: -width}, ( width - indent ) * factor ); });
Как вы могли заметить, в коде мы используем еще одну функцию jQuery — stop (). Она предназначена для остановки, происходящей в данное время анимации элемента. Ей мы передаем один параметр, который означает, что мы хотим очистить очередь анимации. Так же, у нас появляется переменная indent в которую мы записываем текущее значение СSS-свойства text-indent. Эта величина нам понадобится при расчете времени, которое потребуется на анимацию CSS-свойства при его текущем значении.
Код, запускающий анимацию, у нас уже есть, теперь нужен код, который бы ее останавливал. Для этого возьмем метод mouseleave или mouseup. Первый срабатывает, когда мы убираем курсор с объекта, второй – когда отпускаем нажатую кнопку мыши.
$("#gallery .prev").mouseleave ( function () { $("#gallery ul").stop(true); }); $("#gallery .next").mouseleave ( function () { $("#gallery ul").stop(true); });
Итак, у нас уже фактически есть работающее слайд-шоу. Почему фактически? Потому что в браузерах на основе движка Webkit оно не работает. В ходе недолгих разбирательств, мы узнаем, что это браузеры, работающие на этом движке, просчитывают параметры scrollWidth и clientWidth когда документ уже полностью загружен, в отличие от остальных, которые делают это, когда страница показывается пользователю. Поэтому добавляем следующий код:
if ($.browser.webkit && document.readyState != "complete"){ setTimeout( arguments.callee, 100 ); return; }
Он проверяет браузер и состояние готовности страницы. Если движок браузера Webkit и состояние готовности не является «complete», то весь JS-код запускается повторно через 100 мс.
Теперь наше слайд-шоу работает как надо во всех браузерах, но есть еще одна вещь, которой, как мне кажется, не хватает – плавность прокрутки, особенно когда при ее остановке. Давайте сделаем этот процесс более плавным. Для этого нам потребуется специальная библиотека jQuery UI. Она обеспечивает работу с анимацией, эффектами, интерфейсом и всевозможными виджетами. Для нашей задачи нужны функции характера воспроизведения анимации – easing. На странице вы можете наглядно увидеть как работает каждая функция воспроизведения и выбрать подходящую. Эта функция затем передается параметром функции animate. Я выбрал для примера easeOutQuad. Допишем наши функции для прекращения анимации:
$("#gallery .prev").mouseleave ( function () { $("#gallery ul").stop(true); indent = - parseInt ( $("#gallery ul").css("text-indent") ); if ( indent > widthStop ) $("#gallery ul").animate({ textIndent: "+="+widthStop }, widthStop * factorStop, "easeOutQuad" ); else if ( indent > 0 ) $("#gallery ul").animate({ textIndent: 0 }, indent * factorStop, "easeOutQuad" ); }); $("#gallery .next").mouseleave ( function () { $("#gallery ul").stop(true); indent = - parseInt ( $("#gallery ul").css("text-indent") ); var delta = width - indent; if ( delta > widthStop ) $("#gallery ul").animate({ textIndent: "-="+widthStop }, widthStop * factorStop, "easeOutQuad"); else if ( delta > 0 ) $("#gallery ul").animate({ textIndent: -width }, delta * factorStop, "easeOutQuad"); });
Здесь я добавил еще два параметра: widthStop – ширина «тормозного пути», и factorStop — коэффициент для определения времени анимации торможения. В каждой из функций сначала находится текущее значение свойства text-indent, а затем выполняется проверка: больше ли это значение «тормозного пути». Это сделано для того, чтобы не выйти за диапазон прокрутки.
Если у вас хватило терпения правильно проделать все вышеизложенные операции, то в итоге у вас должно получиться примерно такое слайд-шоу.
Скачать рабочий пример.
Слайдшоу не работает в Google Chrome
спасибо! позновательная статья и нужная вещь.
Пробовал реализовать данный метод вручную. Потом плюнул, скачал пример, потом просто перешел по предложенной ссылке — везде одно и то же — статично расположенные во всю длину картинки.
Браузеры: Firefox, Chrome