Адаптивная, автоматическая и ручная навигация

Мы собираемся создать слайдер изображений JavaScript, который имеет функцию автоматического воспроизведения, а также кнопки ручной навигации. Мы не будем использовать какие-либо внешние библиотеки; все родные HTML, CSS и JS.

Мы начнем с размещения всех наших элементов на экране. Нам нужны два компонента: Deck.js и Card.js.

У нас есть 6 элементов для работы:

  • В Deck.js
    1. изображение, которое мы будем использовать в качестве кнопки для перемещения вправо (IMG)
    2. >img, которое мы будем использовать как кнопку для перемещения влево (IMG)
    3. порт просмотра (DIV)
    4. изображения контейнер (DIV)
    5. DIV для хранения наших «переключателей» (DIV)
  • В Card.js
    6. "карточка", которую мы будем использовать для хранения изображения (DIV)
    7. собственно изображение (IMG)

Теперь нам нужно центрировать все на экране. Мы будем использовать комбинацию абсолютных позиций и преобразований.

Теперь, когда все отцентровано, нам нужно расположить карточки слева направо.

Мы пишем простую функцию, которая определяет среднюю карту нашей колоды и перемещает карты слева от этой середины влево, а карты справа от этой середины вправо.

function order_cards() {
  let counter_for_right = 1,
      counter_for_left = middle_card_by_index;
  for (let i = 0; i < images.children.length; i++) {
        images.children[i].style.transitionDuration = '0.0s';
    if (i < middle_card_by_index) {
      images.children[i].style.left = `-${(counter_for_left * 
                                 new_width) - (new_width / 2)}px`;
      counter_for_left--;
    } else if (i > middle_card_by_index) {
      images.children[i].style.left = `${(counter_for_right * 
                                 new_width) + (new_width / 2)}px`;
      counter_for_right++;
    } else {
      images.children[i].style.left = `${new_width / 2}px`;
    }
  }
}

Чтобы наша карусель реагировала, нам нужно изменить размер окна просмотра на основе процентов, а не жестких единиц измерения в пикселях.

Поэтому мы просто выберем 50% и рассчитаем жесткое пиксельное количество на основе ширины окна браузера пользователя; затем мы запустим этот код в прослушивателе событий изменения размера окна.

window.addEventListener('resize', () => {
  img_width_as_percentage = 50;
  img_width_as_percentage = window.innerWidth < 768 ? 100 : 
                            img_width_as_percentage;
  new_width =
        /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera 
          Mini/i.test(navigator.userAgent) ?
            (img_width_as_percentage / 100) * window.screen.width :
            (img_width_as_percentage / 100) * window.innerWidth;
  view_port.style.width = `${new_width}px`;
  order_cards();
});

Мы также изменяем размеры левой и правой кнопок и «радио» кнопок в зависимости от области просмотра и ширины окна.

Теперь, когда у нас есть код изменения размера, каждый раз, когда мы изменяем размер окна браузера, размер карусели изменяется.

У нас есть 3 большие задачи на руках

  1. Кнопка навигации
  2. Навигация «Радио»
  3. Функция автоматического воспроизведения

Основой для ВСЕЙ навигации является вот этот кусок кода

for (let i = 0; i < images.children.length; i++) {
  const updated_position = last_positions[i] + /*some difference*/;
  images.children[i].style.left = `${updated_position}px`;
  last_positions[i] = updated_position;
}

Он говорит следующее: Возьмите текущую позицию всех изображений. Где они на оси X? Добавьте некоторую разность, которая переместит их на новую позицию.

У нас есть массив last_positions, чтобы отслеживать, где наши изображения находятся на экране.

Давайте напишем кнопку навигации

Мы перемещаем изображения влево или вправо на ширину одной карты.
Это делает нашу разницу просто равной ширине одной карты.

for (let i = 0; i < images.children.length; i++) {
  const updated_position = last_positions[i] - new_width;
  images.children[i].style.left = `${updated_position}px`;
  last_positions[i] = updated_position;
}

Давайте закодируем радионавигацию

Мы вычисляем, какую кнопку «радио» нажал пользователь.

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

let new_card = null;
for (let i = 0; i < images.children.length; i++) {
  if (event.target === selection_buttons_container.children[i]) {   
    new_card = i; 
  }
for (let i = 0; i < images.children.length; i++) {
  const updated_position = last_positions[i] + ((current_card - 
                 new_card) * new_width);
  images.children[i].style.left = `${updated_position}px`;
  last_positions[i] = updated_position;
}

Давайте разберемся с автовоспроизведением

Просто поместите нашу логику навигации с помощью кнопки Далее в функцию setInterval().

autoplay_timeout_id = setTimeout(() => {
  autoplay_interval_id = setInterval(() => {
    for (let i = 0; i < images.children.length; i++) {
      const updated_position = last_positions[i] - new_width;
      images.children[i].style.left = `${updated_position}px`;
      last_positions[i] = updated_position;
    }
    current_card = (current_card === number_of_cards_by_index) ?
                                          0 : ++current_card;
    handle_boundaries();
    update_selection();
  }, 1100);
}, 1500);

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

Если вам нужно более подробное руководство, посмотрите мой полный видеоурок на YouTube Объект — это А.

Не забудьте подписаться на нас в Instagram и Twitter, чтобы быть в курсе наших последних руководств по веб-разработке.

Слайд-шоу JavaScript | Отзывчивый, автовоспроизведение с кнопками ручной навигации