Создание изящного и доступного слайдшоу с использованием jQuery

В этом подробном руководстве я расскажу вам, как создать с нуля полезное и доступное для использования на различных устройствах расширение сайта – слайдшоу, используя HTML, CSS и JavaScript (библиотека jQuery). По ходу дела вы познакомитесь с концепцией постепенного улучшения:

Создание изящного и доступного слайдшоу с использованием jQuery

Конечный результат

Здесь вы сможете увидеть демонстрацию виджета, который мы с вами создадим.

Конечный результат

Исходные файлы

Отсюда вы можете загрузить все файлы, составляющие наш виджет для дальнейшего изучения. Помимо окончательной версии jQuery-скрипта, архив содержит PSD-файл с дизайном демонстрационной страницы, равно как и изготовленные в соответствии с дизайном изображения и файлы разметки.

Создание основы

Наиболее важная часть любого сайта – правильная HTML-разметка. В наше время большое внимание принято уделять семантике страницы. Если каждый элемент разметки будет иметь очевидную функцию, то ваша страница будет доступна в любом браузере и на любом устройстве.

Структура нашей страницы подразумевает использование блока <div id="slideshow">, который содержит весь апплет. В этот блок вложен другой блок, с идентификатором “slideContainer”, который содержит сами слайды. Слайды представляют собой блоки класса “slide”.

1. Разметка

<!-- Slideshow HTML -->
<div id="slideshow">
  <div id="slidesContainer">
    <div class="slide">
      <!-- Content for slide 1 goes here -->
    </div>
    <div class="slide">
      <!-- Content for slide 2 goes here. -->
    </div>
    <div class="slide">
      <!-- Content for slide 3 goes here. -->
    </div>
    <div class="slide">
      <!-- Content for slide 4 goes here. -->
    </div>
  </div>
</div>
<!-- Slideshow HTML -->

На этом примере вы можете понять, как увидят наше слайдшоу текстовые браузеры, а также браузеры, не поддерживающие CSS и JavaScript. Заметьте, что никакая часть контента не остаётся скрытой от пользователя.

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

Совет: проверяйте доступность контента с самого начала работы над страницей, и делайте это как можно чаще. Для проверки доступности вашего нового сайта вы можете воспользоваться тестовым веб-приложением WebAnywhere, которое эмулирует работу программы для чтения экрана.

Стили

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

Мы установим свойству overflow для блока “#slidesContainer” значение auto, чтобы в случае недоступности JavaScript слайды можно было перелистывать при помощи линейки прокрутки.

2. Стиль “#slidesContainer”

#slideshow #slidesContainer {
  margin:0 auto;
  width:560px;
  height:263px;
  overflow:auto; /* разрешить скролл */
  position:relative;
}

Ширину “.slide” пришлось уменьшить на 20 пикселей, чтобы вместить в виджет линейку прокрутки.

3. Стиль “.slide”

#slideshow #slidesContainer .slide {
  margin:0 auto;
  width:540px; /* уменьшить на 20 пикселов */
  height:263px;
}

Как видно из этого примера, при отключённом JavaScript наш контент всё ещё доступен: пользователь может просмотреть все слайды при помощи удобной линейки прокрутки в правой части виджета.

В качестве альтернативы мы могли бы назначить классу “slide” свойство “float: left”, и тогда в нижней части виджета появилась бы горизонтальная прокрутка.

CSS-стрелки

Теперь мы создадим правую и левую стрелки при помощи CSS, что избавит нас от необходимости подгружать их в виде графических файлов.

Стрелки являются элементами <span> и внедряются в разметку при помощи функций jQuery. Мы стилизуем для них свойство “pointer”, чтобы курсор вёл себя с нашими стрелками как с настоящими кнопками. Также мы используем приём замещения текста фоновым изображением при помощи свойства “text-indent”.

4. Элементы управления

/** 
 * Slideshow controls style rules.
 */
.control {
  display:block;
  width:39px;
  height:263px;
  text-indent:-10000px;
  position:absolute;
  cursor: pointer;
}
#leftControl {
  top:0;
  left:0;
  background:transparent url(img/control_left.jpg) no-repeat 0 0;
}
#rightControl {
  top:0;
  right:0;
  background:transparent url(img/control_right.jpg) no-repeat 0 0;
}

Самая интересная часть – JavaScript

Теперь, когда нам доступны скрипты, мы как следует развернёмся с нашим дизайном. Использование jQuery облегчит для нас манипуляции с DOM и позволит использовать кроссбраузерные анимационные эффекты.

Общий план

Прежде всего, мы отменим те CSS-стили, которые предназначены специально для работы нашего апплета без JavaScript. Мы уберём прокрутку с “#slideContainer” и вернём слайдам их 20 пикселей. Также мы изменим расположение слайдов в контейнере на горизонтальное.

Затем мы встроим в DOM блок “#slideInner”, который будет соответствовать размеру видимой области нашего виджета, и обернём им слайды.

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

Сначала мы приведём код, осуществляющий выше перечисленные действия, целиком. Затем мы детально рассмотрим некоторые его фрагменты.

5. Весь JavaScript

$(document).ready(function(){
  var currentPosition = 0;
  var slideWidth = 560;
  var slides = $('.slide');
  var numberOfSlides = slides.length;

  // Remove scrollbar in JS
  $('#slidesContainer').css('overflow', 'hidden');

  // Wrap all .slides with #slideInner div
  slides
  .wrapAll('<div id="slideInner"></div>')
  // Float left to display horizontally, readjust .slides width
  .css({
    'float' : 'left',
    'width' : slideWidth
  });

  // Set #slideInner width equal to total width of all slides
  $('#slideInner').css('width', slideWidth * numberOfSlides);

  // Insert left and right arrow controls in the DOM
  $('#slideshow')
    .prepend('<span class="control" id="leftControl">Move left</span>')
    .append('<span class="control" id="rightControl">Move right</span>');

  // Hide left arrow control on first load
  manageControls(currentPosition);

  // Create event listeners for .controls clicks
  $('.control')
    .bind('click', function(){
    // Determine new position
      currentPosition = ($(this).attr('id')=='rightControl') 
    ? currentPosition+1 : currentPosition-1;

      // Hide / show controls
      manageControls(currentPosition);
      // Move slideInner using margin-left
      $('#slideInner').animate({
        'marginLeft' : slideWidth*(-currentPosition)
      });
    });

  // manageControls: Hides and shows controls depending on currentPosition
  function manageControls(position){
    // Hide left arrow if position is first slide
    if(position==0){ $('#leftControl').hide() }
    else{ $('#leftControl').show() }
    // Hide right arrow if position is last slide
    if(position==numberOfSlides-1){ $('#rightControl').hide() } 
    else{ $('#rightControl').show() }
    } 
  });

Создание объектов

Для начала мы инициализируем некоторые переменные, которые будем использовать в работе.

Переменная currentPosition будет хранить порядковый номер слайда, отображаемого в данный момент. Я поместил селектор “$(‘.slide’)” в отдельный объект, чтобы код был более читаемым. Разумеется, вы можете не делать этого, а каждый раз обращаться к слайдам при помощи селектора.

Количество слайдов мы получаем при помощи jQuery-метода “length”.

6. Переменные и константы

var currentPosition = 0;
var slideWidth = 560;
var slides = $('.slide');
var numberOfSlides = slides.length;

Удаление полосы прокрутки

Мы избавимся от прокрутки, установив свойство “overflow” для блока “#slidesContainer” в значение “hidden”. Это отменит “overflow: auto” из нашего стиля.

7. Отмена прокрутки

$('#slidesContainer').css('overflow', 'hidden');

Встраивание блока в DOM

Мы будем перемещать слайды, изменяя «на лету» их атрибут “margin”. Чтобы создать для этого условия, нам нужно поместить все наши слайды в такой блок, размер которого будет в точности соответствовать размеру коллекции слайдов.

8. Создание обёртки “#slideInner” с помощью метода wrapAll()

slides
  .wrapAll('<div  id="slideInner"></div>')

Мы также должны задать размер для “#slideInner”, основываясь на размерах и количестве блоков “.slide”.

9. Задание размера “#slideInner”

$('#slideInner').css('width', slideWidth * numberOfSlides);

Оформление слайдов при помощи JavaScript

Не забудьте, что мы должны изменить размер слайдов и выставить их в ряд при помощи свойства “float”. Эти задачи можно решить одновременно с оборачиванием слайдов в “#slideInner”, соединив вызовы методов css() и wrapAll() в цепочку.

10. Установка “overflow: hidden” для слайдов

slides
  .css('overflow', 'hidden')
  .wrapAll('<div  id="slideInner"></div>')

Встраивание элементов управления в DOM

Мы решили встраивать элементы управления слайд-шоу в DOM при помощи скриптов. Поскольку эти кнопки не функционируют без JavaScript, то и пользователям браузеров, не поддерживающих JavaScript, не нужно их видеть.

Встраивание будет осуществляться при помощи методов prepend() и append(). Они изменяют содержимое выбранного элемента, которым в нашем случае будет блок “#slideshow”. Текст внутри стрелок не имеет значения, поскольку CSS прячет его.

11. Встраивание кнопок

$('#slideshow')
  .prepend('<span class="control" id="leftControl">Moves left</span>')
  .append('<span class="control" id="rightControl">Moves right</span>');

Функция передвижения слайдов стрелками

Мы оживим наши элементы управления при помощи функции manageControls(), которая будет показывать и прятать стрелки в зависимости от порядкового номера текущего слайда.

На первом слайде мы будем скрывать левую стрелку, так как нам в данном случае некуда перемещаться с её помощью. Аналогично поступим с правой стрелкой при показе последнего слайда. Саму работу будут выполнять jQuery-методы hide() и show().

12. Функция manageControls()

function  manageControls(position){
  // position==0 is first slide
  if(position==0)  { $('#leftControl').hide(); }
  else { $('#leftControl').show(); }

  // numberOfSlides-1 is last slides
  if(position==numberOfSlides-1) {  $('#rightControl').hide(); } 
  else { $('#rightControl').show(); }
}

Вызов manageControls() при загрузке DOM

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

Этот вызов ничем не будет отличаться от последующих вызовов. В качестве параметра мы передадим функции переменную currentPosition, которая сразу после загрузки страницы будет содержать значение 0.

13. Вызов manageControls() на событие domready

manageControls(currentPosition);

Назначение manageControls() на событие клика по стрелкам

Последний этап в построении системы jQuery-навигации по слайдам – сопоставление функции manageControls() событиям click обеих кнопок. Это создаст соответствующие обработчики событий, которые передадут управление нашему коду, когда пользователь кликнет по стрелке.

14. Назначение обработчика события методом bind

$('.control').bind('click',  function(){
  // do something when user clicks 
});

Обновление значения currentPosition

Когда пользователь кликает по стрелке, наш скрипт модифицирует значение переменной currentPosition. Клик по стрелке вправо (“#rightControl”) увеличивает его на 1, влево (“#leftControl”) – уменьшает. Эту операцию можно реализовать при помощи тернарного оператора, который представляет собой сокращённую форму оператора условия (if/else).

15. Установка currentPosition тернарным оператором

currentPosition = ($(this).attr('id')=='rightControl') 
                  ?  currentPosition+1 : currentPosition-1;

Вызов manageControls() после обновления currentPosition

После изменения позиции слайда мы должны снова проверить, доступна ли навигация вправо и влево.

16. Вызов manageControls() внутри метода bind

manageControls(currentPosition);

Анимация смены слайда

Наконец, мы готовы передвинуть “#slideInner” влево или вправо, анимировав его CSS-свойство “margin-left”. Значение этого свойства будет представлять собой отрицательное значение произведения ширины слайда на текущую позицию. Например, если мы передвигаемся к третьему слайду, мы должны установить значение “margin-left” в -1120 пикселей.

17. Использование метода animate() для плавного изменения свойства “margin-left

$('#slideInner').animate({
  'marginLeft' : slideWidth*(-currentPosition)
});

Итог

Повторив шаги, изложенные в этом руководстве, вы сможете создать простой апплет-слайдшоу с использованием HTML, CSS и JavaScript (jQuery). Мы применили технику последовательного улучшения, чтобы обеспечить доступность нашего контента в любом браузере.

Обратная связь

Что вы думаете об этой статье? Помогла ли она вам? Что вам было непонятно? С чем вы были не согласны? Можете ли вы исправить мои ошибки или улучшить это руководство? Пожалуйста, выскажитесь или задайте вопросы здесь, в комментариях. Не смущайтесь, мы рады будем вам помочь.

Перевод статьи «Create a Slick and Accessible Slideshow Using jQuery» был подготовлен дружной командой проекта Сайтостроение от А до Я.