Как написать слайдер на javascript для сайта

Обучение веб-разработке на практике эффективнее голой теории: всё наглядно, а полученные в ходе разработки решения можно использовать в будущих проектах. Именно поэтому мы совместно с онлайн-школой GeekBrains подготовили туториал по созданию простого слайдера изображений с объяснением каждого шага. Вот так будет выглядеть финальная версия:

Примечание Данная статья — лишь небольшое погружение в мир фронтенд-разработки, ведь современный веб не ограничивается знанием HTML/CSS/JavaScript. Чтобы стать востребованным веб-разработчиком, необходимо осваивать дополнительные библиотеки и фреймворки, которые часто строго разделены между фронтендом и бэкендом.

Что понадобится?

Можно сразу скачать IDE вроде WebStorm, но при обучении веб-разработке с нуля можно начать и в онлайн-редакторе. Мы будем использовать CodePen — популярный онлайн-редактор для веб-разработчиков с мгновенным отображением результата. Но если вы уже начали работу в какой-либо другой среде и считаете, что она намного удобнее, просто убедитесь, что есть поддержка HTML/CSS/JavaScript.

Пишем код

На различных курсах веб-разработки знакомство с фронтендом начинается с описания основных технологий, а именно:

  • HTML — язык гипертекстовой разметки, на котором пишется «скелет» сайта. Если провести аналогию с домом, то это каркас. Грубо говоря, вы строите разметку, на которую после будет ложиться оформление.
  • CSS — каскадные таблицы стилей или то самое оформление. Вернёмся к примеру с домом: после постройки его нужно облицевать, покрасить, сделать презентабельным, и именно CSS описывает внешний вид сайта.
  • JavaScript — язык программирования, который обеспечивает функциональность. Вы можете взаимодействовать с вещами в вашем доме — включать и выключать свет, бытовую технику, воду и многое другое. Вы точно так же можете взаимодействовать с сайтом, нажимая кнопки, наводя курсор на изображения и заполняя формы. JavaScript обрабатывает все эти взаимодействия, и, как язык сценариев, он может предоставлять правила и логику для определения того, что должно произойти дальше.

HTML

Обучение веб-разработке стоит начать с HTML, так как это каркас сайта. Каждый HTML-документ имеет стандартную структуру:

<!-- Указание типа текущего документа: -->
<!DOCTYPE html>
<html>

  <!-- Содержимое тега <head> не отображается на странице, помогает в работе с данными и хранит информацию для поисковых систем и браузеров: -->
  <head>
    <meta charset="utf-8" />
    <title>Устанавливает заголовок для окна веб-страницы</title>
  </head>

  <!-- Здесь содержится весь отображаемый контент: -->
  <body>
    <p>Текст</p>
    <img src="URL" alt="Изображение">
    <a href="URL">Ссылка</a>
  </body>
</html>

Но в нашем примере прописывать структуру всей страницы не нужно, ведь мы работаем с отдельным компонентом, который потом будет размещаться между тегами <body></body>. Здесь всё просто: у нас есть основной блок (тег <div>), который является родительским и содержит ещё три блока с разными картинками — будущими слайдами:

<!-- Основной блок слайдера -->
<div class="slider">

  <!-- Первый слайд -->
  <div class="item">
    <img src="https://media.tproger.ru/uploads/2020/07/field.jpg">
  </div>

  <!-- Второй слайд -->
  <div class="item">
    <img src="https://media.tproger.ru/uploads/2020/07/rose.jpg">
  </div>

  <!-- Третий слайд -->
  <div class="item">
    <img src="https://media.tproger.ru/uploads/2020/07/leaf.jpg">
  </div>

  <!-- Кнопки-стрелочки -->
  <a class="previous" onclick="previousSlide()">❮</a>
  <a class="next" onclick="nextSlide()">❯</a>
</div>

Обратите внимание, что у каждого тега <div> есть свой класс. Именно по этим классам будет применяться оформление CSS. В тегах <img> мы указываем ссылки на те изображения, которые будут показываться. В атрибуте onclick мы обращаемся к конкретной функции JavaScript, привязывая к кнопке действие по клику.

CSS

В каскадных стилях задаём ширину, высоту, позиционирование, цвет и анимацию. В нашем случае мы работаем отдельно с контейнером слайдера, отдельно с контейнерами картинок, которые прописаны как item, кнопками, добавлением к ним фона и анимацией слайдов:

/* Слайдер: */
.slider{
    max-width: 90%;
    /* Положение элемента устанавливается относительно его исходной позиции: */
    position: relative;
    /* Центрируем по горизонтали: */
    margin: auto;
    height: 300px;
}

/* Картинка масштабируется по отношению к родительскому элементу: */
.slider .item img {
    /* Элемент меняет размер так, чтобы заполнить блок и сохранить пропорции: */
    object-fit: cover;
    width: 100%;
    height: 300px;
}

/* Кнопки назад и вперёд: */
.slider .previous, .slider .next {
    /* Добавляет курсору иконку, когда тот оказывается над кнопкой: */
    cursor: pointer;
    /* Положение элемента задаётся относительно границ браузера: */
    position: absolute;
    top: 50%;
    width: auto;
    margin-top: -22px;
    padding: 16px;
    /* Оформление самих кнопок: */
    color: white;
    font-weight: bold;
    font-size: 16px;
    /* Плавное появление фона при наведении курсора: */
    transition: 0.6s ease;
    /* Скругление границ: */
    border-radius: 0 3px 3px 0;
}
.slider .next {
    right: 0;
    border-radius: 3px 0 0 3px;
}

/* При наведении курсора на кнопки добавляем фон кнопок: */
.slider .previous:hover,
.slider .next:hover {
    background-color: rgba(0, 0, 0, 0.2);
}

/* Анимация слайдов: */
.slider .item {
    animation-name: fade;
    animation-duration: 1.5s;
}
@keyframes fade {
    /* Устанавливаем и изменяем степень прозрачности: */
    from {
        opacity: 0.4
    }
    to {
        opacity: 1
    }
}

Со всеми значениями можно поэкспериментировать в редакторе. Если есть сомнения по поводу какого-то из атрибутов, достаточно его удалить и посмотреть, что изменилось.

JavaScript

Веб-разработчик, обучение которого ограничивается HTML и CSS, — это скорее веб-дизайнер. Мы же переходим к главному языку фронтенда, который способен вдохнуть жизнь в визуальное решение:

/* Устанавливаем стартовый индекс слайда по умолчанию: */
let slideIndex = 1;
/* Вызываем функцию, которая реализована ниже: */
showSlides(slideIndex);

/* Увеличиваем индекс на 1 — показываем следующий слайд: */
function nextSlide() {
    showSlides(slideIndex += 1);
}

/* Уменьшаем индекс на 1 — показываем предыдущий слайд: */
function previousSlide() {
    showSlides(slideIndex -= 1);  
}

/* Устанавливаем текущий слайд: */
function currentSlide(n) {
    showSlides(slideIndex = n);
}

/* Функция перелистывания: */
function showSlides(n) {
    /* Обращаемся к элементам с названием класса "item", то есть к картинкам: */
    let slides = document.getElementsByClassName("item");
    
    /* Проверяем количество слайдов: */
    if (n > slides.length) {
      slideIndex = 1
    }
    if (n < 1) {
        slideIndex = slides.length
    }
  
    /* Проходим по каждому слайду в цикле for: */
    for (let slide of slides) {
        slide.style.display = "none";
    }
    /* Делаем элемент блочным: */
    slides[slideIndex - 1].style.display = "block";    
}

Но не стоит забывать, что не JavaScript единым: современные библиотеки и фреймворки способны упростить разработку и улучшить функциональность веб-компонента. Например, Bootstrap позволяет верстать сайты в разы быстрее, и даже начинающий разработчик может создать рабочий макет с использованием данного фреймворка. А ещё можно написать слайдер на чистом HTML/CSS, чтобы потренировать навыки в вёрстке и каскадных таблицах стилей.

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

Готовый слайдер изображений

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

Теперь вы можете попробовать другие способы реализации, перейти к использованию дополнительных инструментов, таких как Bootstrap:

Или CSS Flexbox:

Можете попрактиковаться на слайдере посложнее, с дополнительными эффектами, опираясь на код из данного проекта:

Бэкенд и дополнительные функции

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

Но не практикой единой: не забывайте учить теорию, чтобы долго не буксовать на сложных задачах. Для этого подойдут книги или видео. Также хорошим способом совместить теорию и практику станут курсы веб-разработки с нуля. Например у GeekBrains как раз открыт набор для тех, кто заинтересован в обучении веб-разработке с трудоустройством. Обещают много практики и сразу полтора года опыта, которые можно добавить в резюме.

В этой статье разберём, как подключить на сайт простой адаптивный слайдер ItcSlider, написанный на чистом CSS и JavaScript. Рассмотрим его HTML-структуру и настройку под разные размеры экрана.

Демо слайдера

1. С одним активным слайдом без зацикливания:

Слайдер с одним активным слайдом без зацикливания

Посмотреть

2. С одновременным показом 3 слайдов:

Слайдер с одновременным отображением 3 слайдов без зацикливания

Посмотреть

3. С зацикливанием:

Адаптивный слайдер с зацикливанием

Посмотреть

4. С индикаторами и автоматической сменой слайдов через 7 секунд:

Слайдер с автоматической сменой слайдов и индикаторами

Посмотреть

5. Слайдер для ротации статей (из дополнительных опций – он обновляет своё состояние при изменении размеров окна браузера):

Слайдер для ротации статей или постов, который может изменять своё состояние при изменении размеров окна браузера

Посмотреть

6. Слайдер в модальном окне:

Слайдер в модальном окне

Посмотреть

7. Несколько слайдеров на странице:

Несколько слайдеров на чистом CSS и JavaScript на странице

Посмотреть

Другие примеры:

  • размещение слайдеров во вкладках таба (открыть).

Коротко о слайдере ItcSlider

ItcSlider – это легкий адаптивный слайдер для сайта, написанный на чистом JavaScript без каких-либо зависимостей.

Характеристики слайдера:

  • макет выполнен на CSS Flexbox;
  • не требует подключения каких-то внешних JavaScript библиотек, таких как jQuery и других;
  • имеет встроенные элементы навигации: кнопки «Предыдущий» и «Следующий», а также индикаторы;
  • доступна функция бесконечной прокрутки или другими словами этот слайдер можно сделать зацикленным;
  • имеется функция автоматического воспроизведения или иными словами смены слайдов через определённые промежутки времени;
  • возможность перелистывания слайдов смахиванием (touch swipe) для устройств с сенсорным экраном, а также перетаскиванием их мышью;
  • размер JavaScript кода около 17 Кбайт.

Кстати, в ItcSlider, в отличие от других очень популярных слайдеров и каруселей (slick, splide, swiper, owlCarousel и так далее), зацикленность выполняется без дополнительного клонирования элементов (то есть, этот слайдер не создаёт копию последнего элемента для его вставки перед первым и первого для его размещения после последнего).

Карусель ItcSlider полностью бесплатна и имеет открытый исходный код (под лицензией MIT). Сам проект находится на GitHub: itc-slider. Поддержать развитие слайдера можно на этой странице.

Исходные коды слайдера расположены на GitHub в репозитории ui-components. В ui-components находится не только этот слайдер, но и другие компоненты пользовательского интерфейса. Данный проект в этом репозитории находится в папке itc-slider.

Слайдер состоит из 2 файлов: itc-slider.css и itc-slider.js.

В этой папке также имеются минимизированные версии этих файлов: chief-slider.min.css и chief-slider.min.js. Их обычно используют для непосредственного подключения к странице.

Скачать все файлы проекта ui-components можно , используя эту ссылку.

После загрузки этих файлов в определённую папку сайта, их нужно подключить к HTML странице. Осуществляется это очень просто:

<!-- CSS -->
<link rel="stylesheet" href="/assets/css/itc-slider.css">
<!-- JavaScript -->
<script src="/assets/js/itc-slider.js" defer></script>

Здесь файлы itc-slider.css и itc-slider.js были загружены на сайт соответственно в /assets/css/ и /assets/js/. Кстати, здесь используется атрибут defer. Он позволяет ускорить загрузку сайта, так как файл itc-slider.js в этом случае будет загружаться в фоне и не мешать браузеру дальше обрабатывать остальную часть страницы.

HTML структура

Перед тем как активировать слайдер вы сначала должны добавить в HTML документ его верстку. HTML структура слайдера, имеющего 3 слайда, и кнопки для переходы к предыдущему и следующему .slider__item:

<div class="itc-slider">
  <div class="itc-slider__wrapper">
    <div class="itc-slider__items">
      <div class="itc-slider__item">
        <!-- Контент 1 слайда -->
      </div>
      <div class="itc-slider__item">
        <!-- Контент 2 слайда -->
      </div>
      <div class="itc-slider__item">
        <!-- Контент 3 слайда -->
      </div>
    </div>
  </div>
  <!-- Кнопки для перехода к предыдущему и следующему слайду -->
  <button class="itc-slider__btn itc-slider__btn_prev"></button>
  <button class="itc-slider__btn itc-slider__btn_next"></button>
</div>

В каждый .itc-slider__item необходимо поместить нужный контент, который будет использоваться для его представления. Это может быть как просто изображение, так и сложный HTML-фрагмент.

Если кнопки для перехода «Назад» и «Вперед» не нужны, то эту часть разметки можно удалить:

<button class="itc-slider__btn itc-slider__btn_prev"></button>
<button class="itc-slider__btn itc-slider__btn_next"></button>

Для включения индикаторов их необходимо вставить в .itc-slider:

<div class="itc-slider">
  ...
  <ol class="itc-slider__indicators">
    <li class="itc-slider__indicator" data-slide-to="0"></li>
    <li class="itc-slider__indicator" data-slide-to="1"></li>
    <li class="itc-slider__indicator" data-slide-to="2"></li>
  </ol>
</div>

Инициализация и настройка слайдера

Активировать слайдер ItcSlider можно без написания JavaScript кода. Для этого к корневому элементу слайдера необходимо добавить атрибут data-slider="itc-slider":

<div class="itc-slider" data-slider="itc-slider">...</div>

После этого скрипт itc-slider.js, как только исходный HTML-документ будет полностью загружен и проанализирован, автоматически инициализирует его как ItcSlider. Иными словами, как только иерархия DOM будет полностью построена, будет вызван вызван статический метод ItcSlider.createInstances(), который создаст экземпляры класса ItcSlider для всех элементов с атрибутом data-slider="itc-slider".

Кроме этого, вы также можете через data-атрибуты передать параметры для настройки слайдера:

<div class="itc-slider" data-slider="itc-slider" data-loop="true" data-autoplay="true" data-interval="7000">

Список параметров:

  • autoplay – включает автоматическую смену слайдов (по умолчанию false);
  • interval – определяет интервал в миллисекундах между автоматической сменой слайдов (по умолчанию 5000);
  • loop – указывает нужно ли зацикливать или нет показ слайдов (по умолчанию true);
  • refresh – включает перерасчет размеров слайдера при изменении ширины HTML документа (по умолчанию true);
  • swipe – разрешает листать слайды свайпом и перемещением курсора мыши при зажатой левой кнопки мыши (по умолчанию true).

Активирование слайдеров через data-атрибуты приведено во всех примерах за исключения демки, котором он отображается в модальном окне. В этом примере он активируется через JavaScript.

Инициализация слайдера через JavaScript осуществляется посредством вызова статического метода getOrCreateInstance:

// .itc-slider – селектор для выбора элемента, который нужно активировать как ItcSlider
const slider = ItcSlider.getOrCreateInstance('.itc-slider');

В этом примере мы элемент, который задали с помощью селектора .itc-slider, активируем как ItcSlider с настройками по умолчанию.

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

// после готовности DOM
document.addEventListener('DOMContentLoaded', () => {
  const slider = ItcSlider.getOrCreateInstance('.itc-slider');
});

Статический метод getOrCreateInstance внутри себя проверяет создан ли экземпляр класса ItcSlider для указанного элемента. Если нет, то вызывает конструктор класса ItcSlider для создания нового экземпляра. На вход статический метод getOrCreateInstance принимает в качестве первого аргумента селектор или DOM-элемент.

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

Пример кода для инициализации с помощью JavaScript всех элементов с классом .itc-slider:

// после готовности DOM
document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('.slider').forEach((el) => {
    ItcSlider.getOrCreateInstance(el);
  });
});

Для настройки слайдера с помощью параметров осуществляется посредством их указания в формате объекта во втором аргументе:

ItcSlider.getOrCreateInstance('.itc-slider', {
  loop: false, // без зацикливания
  swipe: false // без свайпа
});

Список все параметров для настройки мы рассмотрели выше, когда устанавливали их с помощью data-атрибутов.

Количество одновременно отображающихся слайдов

Настройка количества одновременно отображающихся слайдов в области видимости ItcSlider осуществляется посредством CSS:

.itc-slider__item {
  flex: 0 0 100%;
  max-width: 100%;
}

Так как слайды находятся в flex-контейнере, то их ширину мы устанавливаем с помощью свойства flex. Здесь ширина каждого слайда равняется ширине flex-контейнера. Следовательно, в область видимости слайдера будет помещаться только один .itc-slider__item.

Если мы хотим, чтобы показывалось сразу 2 элемента, то тогда в качестве ширины .itc-slider__item нужно установить значение 50%:

.itc-slider__item {
  flex: 0 0 50%;
  max-width: 50%;
}

Эти стили можно добавить в свой файл CSS или, например, непосредственно на страницу, используя тег <style>.

Адаптивно настроить количество одновременно показывающихся слайдов можно посредством медиа-запросов:

/* на маленьких устройствах 1 слайд */
.itc-slider__item {
  flex: 0 0 100%;
  max-width: 100%;
}

/* на средних экранах (ширина больше 768px) 2 слайда */
@media (min-width: 768px) {
  .itc-slider__item {
    flex: 0 0 50%;
    max-width: 50%;
  }
}

/* на больших экранах (ширина больше 1200px) 3 слайда */
@media (min-width: 1200px) {
  .itc-slider__item {
    flex: 0 0 33.3333333333%;
    max-width: 33.3333333333%;
  }
}

Что внутри и некоторые принципы его работы

Как вы уже знаете слайдер ItcSlider в качестве HTML разметки по умолчанию имеет следующую структуру:

<div class="itc-slider">
  <div class="itc-slider__wrapper">
    <div class="itc-slider__items">
      <div class="itc-slider__item">
        <!-- Контент 1 слайда -->
      </div>
      <div class="itc-slider__item">
        <!-- Контент 2 слайда -->
      </div>
      <div class="itc-slider__item">
        <!-- Контент 3 слайда -->
      </div>
    </div>
  </div>
  <!-- Кнопки -->
  <button class="itc-slider__btn itc-slider__btn_prev"></button>
  <button class="itc-slider__btn itc-slider__btn_next"></button>
</div>

Корневой элемент этого компонента имеет класс itc-slider. В нём расположены:

  • .itc-slider__wrapper – используется в качестве обёртки;
  • .itc-slider__btn – кнопки, с помощью которых мы можем перейти соответственно к предыдущему и следующему слайду.

CSS код слайдера очень простой, как мы уже отмечали выше, он находится на GitHub в файле itc-slider.css. В нём нет ничего особенного, здесь мы детальнее остановимся на коде JavaScript.

Сдвиг слайдов в нужном направлении выполняется с помощью приватного метода #move(). Эта метод в зависимости от значения приватного свойства this.#state.direction выполняет изменение положения элемента .itc-slider__items в определённом направлении посредством CSS-трансформации.

Организация зацикленности слайдера выполняется также посредством CSS-трансформаций, но уже не контейнера .itc-slider__items, а посредством самих элементов .itc-slider__item.

Перед тем как понять какой элемент .itc-slider__item и куда нужно переместить, необходимо сначала знать текущее положение и значение трансформации каждого из них. Осуществляется это посредством свойств this.#state.els.index, this.#state.els.order и this.#state.els.translate. Они соответственно содержат порядковый номер или индекс слайда, его текущего положение или порядок, и его значение трансформации. Изначально эти свойства в this.#state.els добавляются на этапе активирования слайдера:

// this.#state.elListItem – это элементы .itc-slider__item
this.#state.elListItem.forEach((el, index) => {
  this.#state.els.push({ el, index, order: index, translate: 0 });
});

Экстремальные значения этих данных содержатся также в свойствах: this.#state.exOrderMin, this.#state.exOrderMax, this.#state.exItemMin, this.#state.exItemMax, this.#state.exTranslateMin и this.#state.exTranslateMax.

Обновление значений этих свойств выполняется посредством вызова метода #updateExProperties() в необходимых местах программы, а их трансформация для организации зацикленности осуществляется при вызове метода #balanceItems().

Как происходит перемещение слайдов для организации зацикленности

Автоматическая смена слайдов через определённые промежутки времени осуществляется с помощью функции setInterval. Она просто вызывает метод #move() через количество миллисекунд, указанное в this.#config.interval:

this.#state.intervalId = setInterval(() => {
  this.#state.direction = 'next';
  this.#move();
}, this.#config.interval);

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

#onMouseEnter() {
  this.#autoplay('stop');
}
#onMouseLeave() {
  this.#autoplay();
}

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

В коде это выполнено с использованием события visibilitychange следующим образом:

#onVisibilityChange() {
  if (document.visibilityState === 'hidden') {
    this.#autoplay('stop');
  } else if (document.visibilityState === 'visible' && this.#config.loop) {
    this.#autoplay();
  }
}

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

#onResize() {
  window.requestAnimationFrame(this.#reset.bind(this));
}

Добавления обработчиков в коде осуществляется через forEach:

Object.keys(this.#state.events).forEach((type) => {
  if (this.#state.events[type][2]) {
    const el = this.#state.events[type][0];
    const fn = this.#state.events[type][1];
    el.addEventListener(type, fn);
  }
});

Как сделать простой слайдер на JavaScript без JQuery

От автора: при изучении JS люди очень часто ищут статьи о том, как создать слайд шоу, карусель изображений, слайдер или ротатор. В этом уроке мы: создадим простенькое слайд шоу без внешних библиотек типа JQuery; разберем проблемы UX и доступности, а также моменты, когда стоит использовать слайд шоу, а когда нет; добавим элементы управления.

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

Наш урок предполагает базовые знания языка JavaScript: функции, событие клика и изменение стилей. Я написал руководство о том, что и в какой последовательности стоит изучать в JavaScript, чтобы быстро начать применять полученные знания на практике.

Создаем простое слайд шоу

Нам понадобится контейнер для слайдов и сами слайды. Вот так это будет выглядеть:

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

<ul id=«slides»>

    <li class=«slide showing»>Slide 1</li>

    <li class=«slide»>Slide 2</li>

    <li class=«slide»>Slide 3</li>

    <li class=«slide»>Slide 4</li>

    <li class=«slide»>Slide 5</li>

</ul>

Базовые стили должны:

Задавать контейнер для слайдов

Располагать слайды один над другим внутри контейнера

Определять поведение слайдов при появлении и исчезновении

Плавно изменять прозрачность для эффекта затухания и появления

Прежде чем смотреть в CSS не забудьте сменить классы и идентификаторы, чтобы не было конфликтов с вашими сайтами. В нашей статье имена классов и идентификаторов будут короткими. Вот наш CSS:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

/*

Первичные стили:

С ними работает слайд шоу

*/

#slides {

    position: relative;

    height: 300px;

    padding: 0px;

    margin: 0px;

    liststyletype: none;

}

.slide {

    position: absolute;

    left: 0px;

    top: 0px;

    width: 100%;

    height: 100%;

    opacity: 0;

    zindex: 1;

    webkittransition: opacity 1s;

    moztransition: opacity 1s;

    otransition: opacity 1s;

    transition: opacity 1s;

}

.showing {

    opacity: 1;

    zindex: 2;

}

Теперь можно добавить стили внешнего вида слайд шоу. Для нашего демо я использовал следующие стили:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

/*

Второстепенные стили:

Внешний вид; можете изменять

*/

.slide {

    fontsize: 40px;

    padding: 40px;

    boxsizing: borderbox;

    background: #333;

    color: #fff;

}

.slide:nthoftype(1) {

    background: red;

}

.slide:nthoftype(2) {

    background: orange;

}

.slide:nthoftype(3) {

    background: green;

}

.slide:nthoftype(4) {

    background: blue;

}

.slide:nthoftype(5) {

    background: purple;

}

JavaScript

JS выполняет одну задачу: прячет текущий слайд и показывает следующий. Для этого нам потребуется сменить названия классов слайдов. Вот наш код JS:

var slides = document.querySelectorAll(‘#slides .slide’);

var currentSlide = 0;

var slideInterval = setInterval(nextSlide,2000);

function nextSlide() {

    slides[currentSlide].className = ‘slide’;

    currentSlide = (currentSlide+1)%slides.length;

    slides[currentSlide].className = ‘slide showing’;

}

Разберемся, что здесь происходит:

Первое, мы с помощью querySelectorAll получаем все слайды из контейнера.

Затем мы создаем переменную для получения текущего слайда.

В конце мы задаем интервал в две секунды для следующего слайда (2000ms).

Подробнее разберем функцию nextSlide:

Мы меняем класс для текущего слайда, чтобы спрятать его. Свойство transition автоматически обрабатывает плавное затухание.

Потом добавляем класс к текущему слайду. Мы используем оператор % на случай, если это был последний слайд, чтобы вернуться к первому. Данный оператор отлично подходит в случаях, когда необходимо выполнять математические операции с циклами типа часов или календаря. В нашем случае 5 слайдов. Посчитаем все числа: 1%5=1, 2%5=2, 3%5=3, 4%5=4, and 5%5=0.

После получения индекса слайда мы меняем класс и показываем новый. И опять прозрачность обрабатывается свойством transition.

Вот и все, мы создали самое простое слайд шоу. По поводу совместимости: Свойство transition не поддерживается в IE9 и ниже, в таком случае эффект затухания сменится на обычный резкий переход к следующему слайду. Базовое слайд шоу:

UX и доступность

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

Слайд шоу может скрывать критический контент

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

По исследованию Университета Нотр-Дам только 1.07% людей кликают на контент в слайд шоу, а из этой маленькой доли людей только 3% кликают на другие слайды помимо первого. Данный пример показывает опасность при расположении критического контента в слайд шоу.

Пользователь может неправильно понять основную задачу сайта

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

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

Фирма по оптимизации конверсии WiderFunnel провела исследования эффективности слайд шоу и пришла к следующему выводу: «Мы протестировали ротаторы специальных предложений и выяснили, что они плохо представляют контент на домашней странице.»

Слайд шоу может разозлить мобильных пользователей

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

Когда применять слайд шоу

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

Создание общего впечатления

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

Когда к контенту легко получить доступ из другого места

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

При использовании техники прогрессивного улучшения

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

Советы по доступности

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

Из статьи: «Для создания доступного слайдера необходимо соблюсти 5 условий:

Пользователь должен быть способен остановить любое движение

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

Обеспечить правильный порядок фокусировки в слайдере

Валидный код и стили

Предоставить понятную альтернативу слайдеру»

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

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

Добавляем элементы управления в слайдер

Пора добавить кнопку паузы, следующий слайд и предыдущий слайд. Кнопка паузы. Сперва, добавьте кнопку в HTML:

<button class=«controls» id=«pause»>Pause</button>

Потом добавьте этот код JS:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

var playing = true;

var pauseButton = document.getElementById(‘pause’);

function pauseSlideshow() {

    pauseButton.innerHTML = ‘Play’;

    playing = false;

    clearInterval(slideInterval);

}

function playSlideshow() {

    pauseButton.innerHTML = ‘Pause’;

    playing = true;

    slideInterval = setInterval(nextSlide,2000);

}

pauseButton.onclick = function() {

    if(playing) {

    pauseSlideshow();

  } else {

    playSlideshow();

  }

};

Что происходит в скрипте:

Переменная playing хранится в моменты, когда слайдер активен.

Кнопку паузы мы занесли в переменную pauseButton, чтобы потом не искать ее по документу.

Функция pauseSlideshow останавливает слайдер, а в кнопку паузы записывает «Play».

Функция playSlideshow запускает слайдер, а в кнопку Play записывает Pause.

В конце мы вешаем обработчик клика, чтобы кнопка play/pause могла ставить слайдер на паузу и запускать его.

Вот так работает наш слайдер с кнопкой паузы:

Кнопки следующий и предыдущий

Сначала добавьте кнопки Next и Previous в HTML:

<button class=«controls» id=«previous»>Previous</button>

<button class=«controls» id=«next»>Next</button>

В JavaScript измените функцию:

function nextSlide() {

    slides[currentSlide].className = ‘slide’;

    currentSlide = (currentSlide+1)%slides.length;

    slides[currentSlide].className = ‘slide showing’;

}

…на:

function nextSlide() {

    goToSlide(currentSlide+1);

}

function previousSlide() {

    goToSlide(currentSlide1);

}

function goToSlide(n) {

    slides[currentSlide].className = ‘slide’;

    currentSlide = (n+slides.length)%slides.length;

    slides[currentSlide].className = ‘slide showing’;

}

Для большей гибкости в скрипте выше мы добавили общую функцию goToSlide. Также чтобы не получить отрицательное значение, мы слегка изменили способ вычисления переменной currentSlide. Для теста вы можете заменить slides.length на свое число и посмотреть, что попадет в currentSlide с изменением значения n. Добавьте код ниже в скрипт, чтобы кнопки начали работать:

var next = document.getElementById(‘next’);

var previous = document.getElementById(‘previous’);

next.onclick = function() {

    pauseSlideshow();

    nextSlide();

};

previous.onclick = function() {

    pauseSlideshow();

    previousSlide();

};

Теперь у нас есть работающие кнопки управления слайдером! Вот так может выглядеть слайдер с кнопками управления и парочкой стилей:

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

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

Фолбэк на случай если JavaScript недоступен

Бывают случаи, когда JavaScript не смог загрузиться, отключен, не поддерживается устройством и т.д. В идеале пользователь даже в таких случаях получит что-то работающее. Какой фолбэк вы создадите зависит от вас. Можно показывать только первое изображение или же все списком.

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

Прячем кнопки если JavaScript недоступен

Прячьте кнопки с помощью CSS по умолчанию.

.controls {

    display: none;

}

Затем показывайте их с помощью JS. Так пользователь увидит кнопки только, если JS активен.

var controls = document.querySelectorAll(‘.controls’);

for(var i=0; i<controls.length; i++){

    controls[i].style.display = ‘inline-block’;

}

Код выше пробегается в цикле по кнопкам и показывает их.

Показывайте изображения списком когда JavaScript недоступен

Сперва, поменяйте в классе .slide position: absolute; на position: static;. Так слайды будут показываться списком по умолчанию.

Затем добавьте JS код и пробегайтесь в цикле по слайдам и меняйте их позиционирование на абсолютное (этот код обязательно должен быть после определения переменной slides):

for(var i=0; i<slides.length; i++) {

    slides[i].style.position = ‘absolute’;

}

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

Заключение

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

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

А вы что думаете? Есть у вас какие-нибудь хорошие истории о слайдерах? Или плохие? Забавные? Пишите об этом в комментариях.

Автор: Gabrielle Gosha

Источник: //www.sitepoint.com/

Редакция: Команда webformyself.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Смотреть

js-slajderВсем привет! 🙂

Поскольку я работаю Fullstack PHP разработчиком, то иногда приходится решать задачи, связанные с фронтэндом, несмотря на то, что я его недолюбливаю 🙂

О моём отношению к всему, что связано с «прекрасным» вы, собственно говоря, могли оценить по дизайну данного сайта, который разрабатывался мною единолично 🙂

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

Вызвана данная необходимость была тем, что в результате должен был получиться JS скрипт, который через сторонний сервис подключался бы на сайт. Следовательно, готовые карусели на JavaScript сразу отпадали, т.к. для их интеграции нужно было в HTML код сайта добавлять подключение библиотеки через тэг script и копировать сами файлы либы на сервер или тянуть их по cdn, но для этого снова потребовалось бы править код ресурса.

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

  • Как сделать JavaScript слайдер: начало
  • Делаем библиотеку JS слайдера
  • JavaScript слайд шоу на базе разработанной библиотеки
  • Интеграция JavaScript слайдера на сайт
  • Добавление новых слайдов в JavaScript карусель
  • Упаковка JS карусели в единый скрипт
  • Самописный JS слайдер — перспективы развития

Как сделать JavaScript слайдер: начало

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

Заказчикам всегда наплевать на то, как код написан, какая у него архитектура, главное — видеть результат!

В итоге, как вы поняли, перед тем, как написать слайдер на JavaScript без jQuery, я решил подыскать готовый и доработать его под свои нужды. Почему без jQuery? Да потому что на целевом ресурсе, куда я планировал подключать свой слайдер через сервис, вызов jQuery в коде был расположен позже скрипта, подключаемого сервисом. Поэтому jQuery конструкции в моём коде просто не воспринимались.

В качестве основы я взял этот JavaScript слайдер изображений — https://codepen.io/gabrieleromanato/pen/pIfoD.

Остановиться я решил именно на нём, т.к. его JS код был написан с применением принципов ООП и классы в нём основываются на прототипах, а не на банальных функциях.

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

Но, к сожалению, в современном мире мои позиции мало кто разделяет, т.к. данный язык развивается сумасшедшими темпами и предпринимает даже попытки завоевать умы бэкенд разработчиков с помощью Node.js как альтернативы Java, PHP, C#, Ruby и других монстров.

В итоге, чтобы банально не остаться без работы, приходится по-тихоньку с JavaScript разбираться. А в выбранной мною реализации слайдера на чистом JavaScript я встретил то, что, как вы поняли, презираю в данном языке. Поэтому я её и выбрал, чтобы был хоть какой-то повод поработать и разобраться с JavaScript ООП и прототипными классами — иначе я бы к ним добровольно никогда в жизни не прикоснулся бы 🙂

На базе найденного мною кода мне необходимо было разработать слайдер на чистом JS во всплывающем окне (такую штуку ещё называют popup, попап и т.д.), который имел бы кнопки переключения слайдов и кликабельные индикаторы текущего слайда. Также нужно было сделать кнопку для закрытия данного окна.

Вот, что у меня получилось в итоге.

Сперва я решил всё реализовать по уму и сделать JavaScript слайдер для сайта в виде библиотеки, подключаемой на сайт одним-единственным скриптом, в котором будут вызываться компоненты слайдера, разбитые по подкаталогам. Назвать её я решил popupSlider.js в честь её изначального предназначения.

Её код можно найти на GitHub по этому адресу — https://github.com/Pashaster12/popupSlider.js

Структура библиотеки вышла следующая:

kak-napisat-js-slajder-svoimi-rukami-struktura

Папка slides предназначена для картинок слайдов. В controls размещены картинки элементов управления JS каруселью (кнопки закрытия слайдера и переключения слайдов). А в assets — статические элементы JS слайдера: HTML разметка и файл с CSS стилями.

Ну, а файл popupSlider.js — это и есть сердце самой библиотеки, в котором прописаны действия JavaScript карусели и устанавливается связь с остальными файлами. Именно его мы и будем подключать на сайте, а он уже будет вызывать остальные.

Я решил начать с HTML разметки нашей JS карусели картинок, которая в моём случае выглядит так:

<div id="cq-popup-bg"></div>
<div id="cq-popup">
    <a id="cq-popup-btclose" href="#"></a>
    <div id="slider">
        <div id="slider-wrapper">
            <div class="slide">
                <img src="slides/1.jpg" alt="" />
                <div class="caption">
                    <div class="caption-container">
                        Text 1
                    </div>
                </div>
            </div>
            <div class="slide">
                <img src="slides/2.jpg" alt="" />
                <div class="caption">
                    <div class="caption-container">
                        Text 2
                    </div>
                </div>
            </div>
            <div class="slide">
                <img src="slides/3.jpg" alt="" />
                <div class="caption">
                    <div class="caption-container">
                        Text 3
                    </div>
                </div>
            </div>
        </div>
        <div id="slider-nav">
            <a href="#" data-slide="0" class="current"></a>
            <a href="#" data-slide="1"></a>
            <a href="#" data-slide="2"></a>
        </div>
        <a href="#" class="horizontal-controls" id="prev"></a>
        <a href="#" class="horizontal-controls" id="next"></a>
    </div>
</div>

Для оформления слайдера на JavaScript в виде попапа я использовал следующие стили:

#slider {
    margin: auto;
    width: 600px !important;
    overflow: hidden;
}
#slider-wrapper {
    width: 9999px;
    height: 343px;
    position: relative;
    transition: left 400ms linear;
}
.slide {
    float: left;
    width: 600px;
    position: relative;
    overflow: hidden;
}
.caption {
    width: 600px;
    height: 110px;
    line-height: 1.5;
    font-size: 15px;
    font-weight: 300;
    text-align: center;
    color: #000;
    display:table;
}
.caption-container {
    display: table-cell;
    vertical-align: middle;
    padding: 0 20px;
}
#slider-nav {
    position: absolute;
    bottom: -36px;
    text-align: center;
    left: 50%;
    transform: translateX(-50%);
}
#slider-nav a {
    width: 8px;
    height: 8px;
    text-decoration: none;
    color: #000;
    display: inline-block;
    border-radius: 50%;
    margin: 0 5px;
    background-color: #fafafa;
}
#slider-nav a.current {
    background-color: #337ab7;
}
.horizontal-controls {
    position: absolute;
    display: inline-block;
    width: 12px;
    height: 20px;
    top: 50%;
    margin-top: -10px;
}
#prev {
    background: url(../controls/arrow_left_inactive.png);
    left: -40px;
}
#prev:hover {
    background: url(../controls/arrow_left_active.png);
}
#next {
    background: url(../controls/arrow_right_inactive.png);
    right: -40px;
}
#next:hover {
    background: url(../controls/arrow_right_active.png);
}
#cq-popup {
    width: 600px;
    z-index: 23;
    left: calc(50%);
    top: calc(50%);
    position: fixed !important;
    background-repeat: no-repeat;
    background-position: right;
    background-color: #fff;
    font-family: "Roboto","Segoe UI","Helvetica","Georgia","Calibri","Verdana";
    transform: translate(-50%, -50%) scale(1);
}
#cq-popup .header {
    display: inline-block;
    font-size: 17px;
    font-weight: 500;
}
#cq-popup > div {
    width: 500px;
    font-size: 22px;
    line-height: 36px;
}
#cq-popup-btclose {
    text-decoration: none;
    position: absolute;
    right: -40px;
    top: 0;
    background: url(../controls/btn_delete_inactive.png);
    height: 16px;
    width: 16px;
}
#cq-popup-btclose:hover {
    background: url(../controls/btn_delete_active.png);
}
#cq-popup-bg {
    position: fixed;
    top:0;
    width: 100%;
    height: 100%;
    background: rgba(51,51,51,0.8);
    z-index: 22;
}

В результате применения данных стилей JS карусель выглядит следующим образом:

kak-sdelat-javascript-slajder-svoimi-rukami

И HTML разметку, и CSS стили я вынес в отдельные файлы popupSlider.html и popupSlider.css, которые расположены в директории assets библиотеки слайдера на JavaScript. Я сделал это специально, чтобы пользователи при использовании данного кода могли без проблем корректировать разметку и оформление, не лазя в JS коде, где вынесенное нужно было бы прописать напрямую.

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

В итоге, я решил просто подключать готовые файлы в главном файле библиотеки popupSlider.js, который для моей постановки задачи принял следующий вид:

function Slider(element) {
    this.loadStatic();
    this.el = document.querySelector(element);
    this.init();
}

Slider.prototype = {
    init: function () {
        this.links = this.el.querySelectorAll("#slider-nav a");
        this.wrapper = this.el.querySelector("#slider-wrapper");
        this.nextBtn = this.el.querySelector("#next");
        this.prevBtn = this.el.querySelector("#prev");
        this.navigate();
    },
    navigate: function () {

        var self = this;

        for (var i = 0; i < this.links.length; ++i) {
            var link = this.links[i];
            link.addEventListener("click", function (e) {
                self.slide(this);
            });
        }

        self.prevBtn.style.display = 'none';

        self.nextBtn.addEventListener('click', function (e) {
            var currentSlideNumber = document.querySelector('#slider-nav a.current').getAttribute("data-slide");
            var nextSlide = document.querySelector('[data-slide="' + (parseInt(currentSlideNumber, 10) + 1) + '"]');

            nextSlide.click();
        }, false);

        self.prevBtn.addEventListener('click', function (e) {
            var currentSlideNumber = document.querySelector('#slider-nav a.current').getAttribute("data-slide");
            var prevSlide = document.querySelector('[data-slide="' + (parseInt(currentSlideNumber, 10) - 1) + '"]');

            prevSlide.click();
        }, false);

        self.close();
    },

    slide: function (element) {
        this.setCurrentLink(element);

        var index = parseInt(element.getAttribute("data-slide"), 10) + 1;
        var currentSlide = this.el.querySelector(".slide:nth-child(" + index + ")");

        this.wrapper.style.left = "-" + currentSlide.offsetLeft + "px";

        if (index < this.links.length)
            this.nextBtn.style.display = 'block';
        else if (index == this.links.length)
            this.nextBtn.style.display = 'none';

        if (index > 1)
            this.prevBtn.style.display = 'block';
        else if (index == 1)
            this.prevBtn.style.display = 'none';
    },

    setCurrentLink: function (link) {
        var parent = link.parentNode;
        var a = parent.querySelectorAll("a");

        link.className = "current";
        this.currentElement = link;

        for (var j = 0; j < a.length; ++j) {
            var cur = a[j];
            if (cur !== link) {
                cur.className = "";
            }
        }
    },

    loadStatic: function () {

        var self = this;

        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = 'assets/popupSlider.css';
        document.head.appendChild(link);

        var sliderHTML = '';

        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'assets/popupSlider.html', false);
        xhr.send();
        if (xhr.status != 200) {
            alert('Can not load the popupSlider.html. Got the error ' + xhr.status + ': ' + xhr.statusText);
        } else {
            sliderHTML = xhr.responseText;
        }

        var div = document.createElement('div');
        div.innerHTML = sliderHTML;
        document.body.appendChild(div);
    },

    close: function () {
        document.getElementById('cq-popup-btclose').onclick = function () {
            document.getElementById('cq-popup-bg').remove();
            document.getElementById('cq-popup').remove();
        }
    }
};

Немного комментариев по поводу приведённого кода. Содержимое файла popupSlider.js является одним JavaScript классом Slider, который, как и в PHP, содержит конструктор и методы класса. Только в JS определение конструктора, в отличие от PHP, является обязательным.

Конструктор определяется с помощью следующей конструкции:

function Slider(element) {
    //код конструктора
}

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

Сами методы класса будут находиться внутри прототипа и будут доступны для всех экземпляров данного JavaScript класса. JS прототип в моём случае описывается следующей конструкцией:

Slider.prototype = {
    //методы
}

Вызываться за пределами тела класса они будут следующим образом:

var slider = new Slider();
slider.class_method();

А внутри самого кода класса доступен следующий способ:

this.class_method();

Главное только не забывать, что в JavaScript значение this зависит от контекста вызова, поэтому в телах некоторых методов, в которых нужно было вызывать методы и свойства класса, присутствует такая конструкция:

var self = this;
self.class_method(); //чтобы обратиться к методу, находящемся на уровень выше кода описываемого метода

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

loadStatic()

Самый первый метод, вызывающийся при создании экземпляра класса в конструкторе. Отвечает за добавление в HTML кода страницы сайта HTML разметки слайдера и файла со стилями.

Сначала в памяти создаётся новый тэг link с помощью JavaScript функции document.createElement() и ему присваиваются значения всех необходимых атрибутов, в том числе и путь к CSS файлу со стилями JS слайдера. И, в конце-концов, он добавляется в HTML страницы с помощью JavaScript метода appendChild() в конец секции head, где и должны подключаться CSS файлы стилей.

Далее мы делаем то же самое для файла с HTML разметкой нашего слайдера на чистом JavaScript. Вот только здесь есть маленький нюанс: просто так HTML файл внутри такого же подключить нельзя, как мы сделали это с CSS файлом. Для этого есть специальные библиотеки, например, для того, чтобы подключить HTML в HTML, отлично подходит либа от w3.org — https://www.w3schools.com/howto/howto_html_include.asp

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

В итоге, я решил получать содержимое HTML файла внутри JavaScript кода и загружать его в новый div элемент, создаваемый в памяти, как я делал это ранее для подключения CSS файла в JavaScript. Сгенерированный элемент подключается в самый конец секции body HTML кода страницы сайта.

Если хотите вставить div с разметкой слайдера не просто в конец body, а в какой-то конкретный контейнер, то можете вместо следующего кода:

var div = document.createElement('div');
div.innerHTML = sliderHTML;
document.body.appendChild(div);

Прописать следующее, указав нужный идентификатор целевого контейнера (в моём случае HTML JS слайдера будет расположен в элементе с id popupSlider):

var target = document.querySelector( "#popupSlider" );
target.innerHTML = sliderHTML;

init()

Метод, который вызывается в конструкторе после loadStatic(), и нужен для инициализации свойств класса, соответствующих основным HTML элементам, к которым мы будем обращаться в следующем коде.

В конце вызывается метод navigate().

navigate()
В данном методе происходит указание действий, происходящих при клике на кнопки переключения слайдов и элементы навигации, расположенные под самим слайдером, в виде кружочков.

Сам JavaScript код смены слайдов для удобства я вынес в отдельный метод slide(), а в данном я только навешиваю его на событие click для каждой круглой кнопки в цикле.

При клике на кнопки «предыдущий слайд»/»следующий слайд» я, как видите, решил всего лишь эмулировать нажатие на соответствующий кружочек, определяя нужный относительно текущего, у которого имеется CSS класс current.

slide(element)

Метод, «отвечающий за магию» самой JavaScript карусели, в котором содержится код, меняющий слайды местами. В самом начале вызывается метод setCurrentLink(), о котором мы поговорим чуточку позже.

В качестве входного параметра в него передаётся объект кнопки навигации JS слайдера в виде кружочка.

Само переключение слайдов работает следующим образом:

  1. Все слайды у нас оформлены в виде блоков одинаковых размеров, идущих друг за другом. Окно слайдера — это лишь видимая часть элемента, содержащего все слайды.
  2. Мы определяем смещение левого края текущего слайда от левого края родительского элемента с помощью свойства offsetLeft.
  3. И сдвигаем родительский элемент на это значение, чтобы в окне слайдера у нас отображался необходимый элемент.

В конце метода описано поведение для кнопок «предыдущий слайд»/»следующий слайд», оформленных в виде стрелок влево/вправо соответственно. Если текущий слайд — первый из всего списка, то кнопка перехода к предыдущему слайду скрывается. Если последний, то убираем кнопку перехода к следующему слайду.

setCurrentLink(link)

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

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

Логика выделения текущего элемента проста:

  1. Получаем объект родительского элемента, которым в нашем случае выступает контейнер с идентификатором slider-nav.
  2. Получаем все навигационные элементы в виде массива ссылок.
  3. Выделяем элемент, полученный на входе, путём добавления ему классу current.
  4. В цикле перебираем все навигационные элементы и у всех, кроме текущего, очищаем значение класса. Это нужно для того, чтобы снять выделение с элемента, которым был текущим до данного вызова функции.

close()

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

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

Сам метод вызывается внутри описанного ранее navigate(), который содержит в себе все сценарии действий, происходящих на нашем JavaScript слайдере.

Кстати, если вы захотите сделать закрытие слайдера при клике за его пределами, то достаточно в данный метод добавить следующий код:

document.getElementById('cq-popup-bg').onclick = function () {
document.getElementById('cq-popup-bg').remove();
document.getElementById('cq-popup').remove();

JavaScript слайд шоу на базе разработанной библиотеки

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

На самом деле, реализация JavaScript слайд шоу отличается от обычного слайдера совсем незначительно. Разница заключается лишь в том, что в слайд шоу слайды переключаются автоматически с заданным временным интервалом, а в случае обычной JS карусели они меняются вручную с помощь элементов навигации.

Для автоматической прокрутки слайдов я добавил в самый конец своего класса следующий метод:

slideShow: function (timeout) {
    var sliderCount = this.links.length;
    var self = this;

    this.slideCycle = setInterval(function () {
        var currentSlideNumber = document.querySelector('#slider-nav a.current').getAttribute("data-slide");
        var slideId = parseInt(currentSlideNumber, 10) + 1;
        self.slide(document.querySelector('[data-slide="' + (sliderCount == slideId ? 0 : slideId) + '"]'));
    }, timeout);
}

Что здесь происходит — думаю, понятно. Для создания данного метода я скопировал код из события клика на кнопки ручного переключения слайдов и разместил его внутри вызова JavaScript функции setInterval(), которая выполняет указанное действие через заданный промежуток времени.

Сценарий действия передаётся первым аргументом в виде анонимной функции, а временной интервал — вторым, который я решил сделать в виде переменной, значение которой передаётся при вызове slideShow().

Единственная модификация кода внутри setInterval(), которая потребовалась, — это определение количества слайдов и сравнение с ним индекса текущего слайда для зацикленности автоматического переключения.

Ну, и для того, чтобы данный код заработал, сам метод необходимо вызвать. Я решил сделать это всё в том же navigate(), который как раз и является сборником всяких сценариев. Вызов я разместил в самом конце, передав в качестве аргумента значение временного интервала для автоматической смены слайдов в нашем JS слайд шоу (я выбрал 2000 милисекунд или 2 секунды, вы можете по необходимости изменять это число):

self.slideShow(2000);

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

По идее, всё должно работать. Если нет — изучайте ошибки в консоли браузера и делитесь ими в комментариях.

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

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

Для прерывания автоматического показа слайдов JavaScript карусели я решил воспользоваться стандартной JS функцией clearInterval(), которой в качестве аргумента передаю идентификатор временного интервала, возвращаемого функцией setInterval() при его установке.

В итоге, получился следующий код, который я решил не оформлять отдельным методом:

clearInterval(self.slideCycle);

И разместил его в местах описания действий при кликах на различные элементы навигации, т.е. в следующих:

link.addEventListener("click", function (e) {...});

self.prevBtn.addEventListener('click', function (e) {...});

self.nextBtn.addEventListener('click', function (e) {...});

Вызов clearInterval() лучше делать поближе к самому событию клика, главное, чтобы перед ним, а не после.

Интеграция JavaScript слайдера на сайт

Итак, наш слайдер на чистом JS готов. Осталось теперь только подключить его на сайт.

Для этого необходимо выполнить последовательно следующие шаги, которые являются стандартными действиями при интеграции каких-либо сторонних JavaScript библиотек вообще.

Шаг 1. Копируем файлы библиотеки к себе на сайт в отдельный каталог.
Шаг 2. Добавляем следующий код в HTML страниц, на которых необходимо будет отображение слайдера, разместив его перед закрывающимся тэгом body:

<script type="text/javascript" src="/каталог_слайдера/popupSlider.js"></script>

Шаг 3. Размещаем следующий код вызова JS карусели в каком-либо существующем JavaScript файле, который подключается на странице после подключения самого слайдера:

var aSlider = new Slider("#slider");

Как видите, данный код, — это, по сути, создание объекта класса Slider, который содержится в popupSlider.js. Именно поэтому его вызов должен быть только после подключения самого файла класса на страницу.

Добавление новых слайдов в JavaScript карусель

Здесь всё очень просто. Поскольку слайды у нас берутся из отдельной директории библиотеки slides, то при добавлении новых картинок нужно будет просто закинуть в неё нужные файлы, задав им предварительно такой же размер, как и у других.

А затем в коде файла assets/popupSlider.html добавить новый блок в контейнер с id slider-wrapper:

<div class="slide">
    <img src="slides/new_slide.jpg" alt="" />
    <div class="caption">
        <div class="caption-container">
           Text
        </div>
    </div>
</div>

В принципе, можете просто скопировать аналогичный существующий и изменить в нём путь к файлу изображения и текст подписи (если она вообще будет нужна).

Также необходимо будет добавить новый элемент навигации в виде кружочка, т.к. на данный момент автоматическое его добавление пока не реализовано. Для этого нужно будет добавить следующий код в контейнер с id slider-nav, прописав его в самом конце:

<a href="#" data-slide="id"></a>

Значение атрибута data-slide должно быть больше самого большого у остальных элементов. Достаточно всего лишь увеличить максимальное текущее на единицу.

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

Всё, слайдер на JavaScript готов и подключен. Я лично рекомендую использовать данный вариант на практике, если он вам вообще пригодится 🙂

Для ускорения работы его, кстати, можете ещё дополнительно сжать статические компоненты: CSS, HTML и JavaScript файлы. Я не стал этого делать и предлагать вам минифицированный код, потому что систем сборок фронтэнда сейчас очень много: Gulp, Grunt, Webpack и другие. И у каждой из них свои алгоритмы сжатия и подключения файлов.

К тому же, минифицированные результаты на разных ОС могут работать по-разному. В общем, причин много.

Да и сами исходники у меня вышли, я считаю, не такие уж тяжеловесные, что нуждаются в данной процедуре. Но если же вам они будут необходимы, то настройте минификацию самостоятельно с учётом вашей ОС и сборщика.

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

Так вот, в завершение своего сегодняшнего повествования я решил поделиться с вами финальной версией своей JavaScript карусели, которую я использовал на практике. Возможно, кому-то данный способ будет полезен. Он также пригодится тем, кто будет подключать предоставленную мною библиотеку через системы сборки Webpack, Gulp, Grunt и при этом столкнётся с проблемой правильности файловых путей.

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

Скрипт в моём случае состоит из двух частей. В первой части располагалось содержимое файла popupSlider.js, которое я второй раз не буду приводить. Вставьте его самостоятельно, убрав из кода класса описание метода loadStatic() и его вызов, т.к. они нам не понадобятся.

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

Там у нас будет происходить добавление на страницу HTML/CSS кода JS карусели и создание объекта класса Slider, что равносильно активации самого слайдера.

Схематично код выглядит следующим образом:

/* содержимое popupSlider.js без описания метода loadStatic() и его вызова */

document.addEventListener('DOMContentLoaded', function(){
    var str = '
         <style>
             /*css код*/
         </style>
         /* html код */
         ';

    var div = document.createElement('div');
    div.innerHTML = str;
    document.body.appendChild(div);

    var aSlider = new Slider("#slider");

Поскольку в моём случае вариант загрузки файлов на сервер был вообще закрыт, мне пришлось загрузить файлы картинок элементов управления JavaScript каруселью на облако и вместо путей к ним в HTML и CSS коде прописать ссылки, сгенерированные при сохранении.

Если у вас таких сложностей нет, то можете ничего не менять, но не забыть скопировать каталоги slides и controls библиотеки на сервер и указать правильные пути к ним.

Самописный JS слайдер — перспективы развития

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

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

Так что если вам, как и мне, нужна будет кодовая база для экспериментов и вы располагаете хоть каким-то лишним свободным временем — копируйте себе код описанного мною JavaScript слайдера или присоединяйтесь к контрибьюторам на GitHub. Репозиторий открытый, а ссылку на него я предоставил в начале статьи.

Если вы хотите прокачать свои фронтэнд скилы на моём творении, могу вам даже подкинуть небольшой список правок и доработок, в которых нуждается код и которые, возможно, будут интересны вам в плане их реализации:

  1. сделать внешний конфиг, чтобы можно было удобно настраивать слайдер;
  2. сделать возможность встраивания слайдера внутрь страницы (сейчас оформлен только в виде попапа);
  3. асинхронная загрузка HTML кода (сейчас сделана синхронная, которая многими браузерами помечается как устаревший вариант);
  4. оформить библиотеку в виде пакета, NPM, Bower или другого пакета, чтобы его можно было устанавливать и оперировать зависимостями с помощью пакетных менеджеров;
  5. сделать вёрстку адаптивной для использования JS карусели на различных устройствах;
  6. сделать переключение слайдов по событию Swipe для мобильных пользователей.

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

Прошу мой код строго не судить, т.к., я как я уже говорил, Frontend спецом я себя не считаю и не являюсь. Также я открыт для всех ваших замечаний по стилю кодирования и надеюсь, что смогу что-то у вас перенять, а вы — у меня, т.е. выполнить основное предназначение разработки и поддержки OpenSource продукции.

Вступайте в сообщества проекта, подписывайтесь на обновления и можете даже помочь мне материально с помощью формы прямо под самой статьёй, если я чем-то смог вам помочь или вам просто нравится то, чем я занимаюсь 🙂

У меня всё! Всем добра! 🙂

P.S.: если вам нужен сайт либо необходимо внести правки на существующий, но для этого нет времени и желания, могу предложить свои услуги.

Более 5 лет опыта профессиональной разработки сайтов. Работа с PHP, OpenCart, WordPress, Laravel, Yii, MySQL, PostgreSQL, JavaScript, React, Angular и другими технологиями web-разработки.

Опыт разработки проектов различного уровня: лендинги, корпоративные сайты, Интернет-магазины, CRM, порталы. В том числе поддержка и разработка HighLoad проектов. Присылайте ваши заявки на email cccpblogcom@gmail.com.

И с друзьями не забудьте поделиться 😉

Простой слайдер на чистом css и javascript, не имеет практической ценности, исключительно для практики. Несколько картинок, возможность автопрокрутки, кнопки вперед и назад, индикатор текущего слайда. Для начала подготовим простую страницу, создадим html-разметку и файл стилей — а потом напишем js-класс Slider.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Slider</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: Arial, Helvetica, sans-serif;
        }
        .container {
            max-width: 900px;
            margin: 0px auto;
        }
    </style>
    <link rel="stylesheet" href="slider.css">
    <script src="slider.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // здесь будем создавать экземпляр js-класса слайдера
        });
    </script>
</head>
<body>
    <div class="container">
        <!-- здесь будет html-разметка слайдера -->
    </div>
</body>
</html>

Создаем html-разметку слайдера

<body>
    <div class="container">
        <div class="carousel">
            <div class="carousel-window">
                <div class="carousel-slides">
                    <div class="carousel-item">
                        <img src="img/slide-1.jpg" alt="">
                    </div>
                    <div class="carousel-item">
                        <img src="img/slide-2.jpg" alt="">
                    </div>
                    <div class="carousel-item">
                        <img src="img/slide-3.jpg" alt="">
                    </div>
                    <div class="carousel-item">
                        <img src="img/slide-4.jpg" alt="">
                    </div>
                    <div class="carousel-item">
                        <img src="img/slide-5.jpg" alt="">
                    </div>
                </div>
            </div>
            <a href="#" class="carousel-prev">
                <span class="carousel-prev-icon">&lt;</span>
            </a>
            <a href="#" class="carousel-next">
                <span class="carousel-next-icon">&gt;</span>
            </a>
        </div>
    </div>
</body>

Создаем файл стилей слайдера

.carousel {
    margin: 0 auto;
    position: relative;
}
    .carousel .carousel-indicators {
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
        z-index: 15;
        display: flex;
        justify-content: center;
        padding: 10px;
        list-style: none;
    }
        .carousel .carousel-indicators li {
            flex: 0 1 auto;
            width: 20px;
            height: 20px;
            margin-right: 5px;
            margin-left: 5px;
            cursor: pointer;
            background-color: #343a40;
            border: 2px solid #fff;
            border-radius: 50%;
        }
        .carousel .carousel-indicators .active {
            background-color: #025fff;
        }
    .carousel .carousel-window {
        width: 100%;
        height: 500px;
        position: relative;
        overflow: hidden;
    }
    .carousel .carousel-slides {
        height: 100%;
        display: flex;
        transition: transform 0.5s;
    }
    .carousel .carousel-item {
        height: 100%;
    }
        .carousel .carousel-item img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    .carousel .carousel-prev, .carousel .carousel-next {
        position: absolute;
        top: 0;
        bottom: 0;
        z-index: 1;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 15%;
        color: #fff;
        opacity: 0.7;
        text-align: center;
        font-size: 40px;
        text-decoration: none;
    }
    .carousel .carousel-prev:hover, .carousel .carousel-next:hover {
        opacity: 1;
        background-color: rgba(0, 0, 0, 0.2);
    }
    .carousel .carousel-prev {
        left: 0;
    }
    .carousel .carousel-next {
        right: 0;
    }

Создаем js-класс слайдера

/*
 * <div class="carousel"> width: 100% (от контейнера .container 900px)
 *     <div class="carousel-window"> width: 100% (от родителя 900px); height: 500px
 *         <div class="carousel-slides"> display: flex, style.width = 300% (2700px)
 *             <div class="carousel-item">...</div> style.width = 33.33333% (900px)
 *             <div class="carousel-item">...</div> style.width = 33.33333% (900px)
 *             <div class="carousel-item">...</div> style.width = 33.33333% (900px)
 *         </div>
 *     </div>
 * </div>
 * Можно сказать, что carousel-window представляет собой окно просмотра 900x500px,
 * в этом окне просмотра виден одновременно только один кадр (слайд). Элемент
 * carousel-slides представляет из себя цепочку из трех кадров (как в кино). Эти
 * кадры выстроены по горизонтали благодаря display:flex. При клике на кнопки
 * next и prev — цепочка смещается влево, и в окне просмотра появляется очередной
 * кадр (слайд).
 */

class Slider {
    constructor(slider, autoplay = true) {
        // элемент div.carousel
        this.slider = slider;
        // все кадры (слайды)
        this.allFrames = slider.querySelectorAll('.carousel-item');
        // цепочка кадров
        this.frameChain = slider.querySelector('.carousel-slides');
        // кнопка «вперед»
        this.nextButton = slider.querySelector('.carousel-next');
        // кнопка «назад»
        this.prevButton = slider.querySelector('.carousel-prev');

        this.index = 0; // индекс кадра, который сейчас в окне просмотра
        this.length = this.allFrames.length; // сколько всего есть кадров
        this.autoplay = autoplay; // включить автоматическую прокрутку?
        this.paused = null; // чтобы можно было выключать автопрокрутку

        this.init(); // инициализация слайдера
    }

    init() {
        this.dotButtons = this.dots(); // создать индикатор текущего кадра

        // все кадры должны быть одной ширины, равной ширине окна просмотра;
        // если кадров три, то ширина каждого кадра будет 100/3 = 33.33333%
        // от ширины контейнера .carousel-slides, то есть 900 пикселей
        this.allFrames.forEach(frame => frame.style.width = 100/this.length + '%');
        // ширина цепочки кадров должна равна ширине всех кадров, то есть
        // 900*3 = 2700 пикселей; но удобнее задать в процентах от родителя,
        // если кадров три, то ширина контейнера кадров будет 100*3 = 300%
        this.frameChain.style.width = 100 * this.length + '%';

        this.nextButton.addEventListener('click', event => { // клик по кнопке «вперед»
            event.preventDefault();
            this.next();
        });

        this.prevButton.addEventListener('click', event => { // клик по кнопке «назад»
            event.preventDefault();
            this.prev();
        });

        // клики по кнопкам индикатора текущего кадра
        this.dotButtons.forEach(dot => {
            dot.addEventListener('click', event => {
                event.preventDefault();
                const index = this.dotButtons.indexOf(event.target);
                if (index === this.index) return;
                this.goto(index);
            });
        });

        if (this.autoplay) { // включить автоматическую прокрутку?
            this.play();
            // когда мышь над слайдером — останавливаем автоматическую прокрутку
            this.slider.addEventListener('mouseenter', () => clearInterval(this.paused));
            // когда мышь покидает пределы слайдера — опять запускаем прокрутку
            this.slider.addEventListener('mouseleave', () => this.play());
        }
    }

    // перейти к кадру с индексом index
    goto(index) {
        // изменить текущий индекс...
        if (index > this.length - 1) {
            this.index = 0;
        } else if (index < 0) {
            this.index = this.length - 1;
        } else {
            this.index = index;
        }
        // ...и выполнить смещение
        this.move();
    }

    // перейти к следующему кадру
    next() {
        this.goto(this.index + 1);
    }

    // перейти к предыдущему кадру
    prev() {
        this.goto(this.index - 1);
    }

    // рассчитать и выполнить смещение
    move() {
        // на сколько нужно сместить, чтобы нужный кадр попал в окно
        const offset = 100/this.length * this.index;
        this.frameChain.style.transform = `translateX(-${offset}%)`;
        this.dotButtons.forEach(dot => dot.classList.remove('active'));
        this.dotButtons[this.index].classList.add('active');
    }

    // запустить автоматическую прокрутку
    play() {
        this.paused = setInterval(() => this.next(), 3000);
    }

    // создать индикатор текущего слайда
    dots() {
        const ol = document.createElement('ol');
        ol.classList.add('carousel-indicators');
        const children = [];
        for (let i = 0; i < this.length; i++) {
            let li = document.createElement('li');
            if (i === 0) li.classList.add('active');
            ol.append(li);
            children.push(li);
        }
        this.slider.prepend(ol);
        return children;
    }
}

Создаем экземпляр js-класса

<link rel="stylesheet" href="slider.css">
<script src="slider.js"></script>
<script>
    document.addEventListener('DOMContentLoaded', function() {
        new Slider(document.querySelector('.carousel'));
    });
</script>

Еще одни вариант

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

/*
 * <div class="carousel"> width: 100% (от контейнера .container 900px)
 *     <div class="carousel-window"> width: 100% (от родителя 900px); height: 500px
 *         <div class="carousel-slides"> display: flex, style.width = 300% (2700px)
 *             <div class="carousel-item">...</div> style.width = 33.33333% (900px)
 *             <div class="carousel-item">...</div> style.width = 33.33333% (900px)
 *             <div class="carousel-item">...</div> style.width = 33.33333% (900px)
 *         </div>
 *     </div>
 * </div>
 */

class Slider {
    constructor(slider, {autoplay = true, inFrame = 1, offset = 1} = {}) {
        // элемент div.carousel
        this.slider = slider;
        // кол-во элементов в одном кадре
        this.inFrame = inFrame;
        // на сколько элементов смещать
        this.offset = offset;

        // все элементы слайдера
        this.allItems = slider.querySelectorAll('.carousel-item');
        // сколько всего элементов
        this.itemCount = this.allItems.length;

        // все кадры слайдера
        this.allFrames = this.frames();
        // сколько всего кадров
        this.frameCount = this.allFrames.length;
        // индекс кадра в окне просмотра
        this.frameIndex = 0;

        // контейнер для элементов
        this.wrapper = slider.querySelector('.carousel-slides');
        // кнопка «вперед»
        this.nextButton = slider.querySelector('.carousel-next');
        // кнопка «назад»
        this.prevButton = slider.querySelector('.carousel-prev');

        this.autoplay = autoplay; // включить автоматическую прокрутку?
        this.paused = null; // чтобы можно было выключать автопрокрутку

        this.init(); // инициализация слайдера
    }

    init() {
        this.dotButtons = this.dots(); // создать индикатор текущего кадра

        // если всего 10 элементов, то ширина одного элемента составляет 1/10
        // ширины контейнера .carousel-slides, то есть 100/10 = 10%
        this.allItems.forEach(item => item.style.width = 100 / this.itemCount + '%');
        // ширина контейнера должна вмещать все элементы: если элементов 10,
        // в окне просмотра 3 элемента, тогда ширина контейнера равна ширине
        // трех окон просмотра (300%) плюс ширина одного элемента 33.33333%,
        let wrapperWidth = this.itemCount / this.inFrame * 100;
        this.wrapper.style.width = wrapperWidth + '%';

        this.nextButton.addEventListener('click', event => { // клик по кнопке «вперед»
            event.preventDefault();
            this.next();
        });

        this.prevButton.addEventListener('click', event => { // клик по кнопке «назад»
            event.preventDefault();
            this.prev();
        });

        // клики по кнопкам индикатора текущего кадра
        this.dotButtons.forEach(dot => {
            dot.addEventListener('click', event => {
                event.preventDefault();
                const frameIndex = this.dotButtons.indexOf(event.target);
                if (frameIndex === this.frameIndex) return;
                this.goto(frameIndex);
            });
        });

        if (this.autoplay) { // включить автоматическую прокрутку?
            this.play();
            // когда мышь над слайдером — останавливаем автоматическую прокрутку
            this.slider.addEventListener('mouseenter', () => clearInterval(this.paused));
            // когда мышь покидает пределы слайдера — опять запускаем прокрутку
            this.slider.addEventListener('mouseleave', () => this.play());
        }
    }

    // перейти к кадру с индексом index
    goto(index) {
        if (index > this.frameCount - 1) {
            this.frameIndex = 0;
        } else if (index < 0) {
            this.frameIndex = this.frameCount - 1;
        } else {
            this.frameIndex = index;
        }
        // ...и выполнить смещение
        this.move();
    }

    // перейти к следующему кадру
    next() {
        this.goto(this.frameIndex + 1);
    }

    // перейти к предыдущему кадру
    prev() {
        this.goto(this.frameIndex - 1);
    }

    // рассчитать и выполнить смещение
    move() {
        // на сколько нужно сместить, чтобы нужный кадр попал в окно
        const offset = 100 / this.itemCount * this.allFrames[this.frameIndex];
        this.wrapper.style.transform = `translateX(-${offset}%)`;
        this.dotButtons.forEach(dot => dot.classList.remove('active'));
        this.dotButtons[this.frameIndex].classList.add('active');
    }

    // запустить автоматическую прокрутку
    play() {
        this.paused = setInterval(() => this.next(), 3000);
    }

    // создать индикатор текущего кадра
    dots() {
        const ol = document.createElement('ol');
        ol.classList.add('carousel-indicators');
        const children = [];
        for (let i = 0; i < this.frameCount; i++) {
            let li = document.createElement('li');
            if (i === 0) li.classList.add('active');
            ol.append(li);
            children.push(li);
        }
        this.slider.prepend(ol);
        return children;
    }

    // индекс первого элемента каждого кадра
    frames() {
        // все наборы элементов, которые потенциально могут быть кадрами
        let temp = [];
        for (let i = 0; i < this.itemCount; i++) {
            // этот набор из this.inFrame элементов без пустого места
            if (this.allItems[i + this.inFrame - 1] !== undefined) {
                temp.push(i);
            }
        }
        // с учетом того, что смещение this.offset может быть больше 1,
        // реальных кадров будет меньше или столько же
        let allFrames = [];
        for (let i = 0; i < temp.length; i = i + this.offset) {
            allFrames.push(temp[i]);
        }
        // в конце могут быть элементы, которые не могут образовать целый кадр (без пустоты),
        // такой кадр вообще не попадает в окно просмотра; вместо него показываем последний
        // целый кадр из числа потенциальных; при этом смещение будет меньше this.offset
        if (allFrames[allFrames.length - 1] !== temp[temp.length - 1]) {
            allFrames.push(temp[temp.length - 1]);
        }
        return allFrames;
    }
}
<link rel="stylesheet" href="slider.css">
<script src="slider.js"></script>
<script>
    document.addEventListener('DOMContentLoaded', function() {
        new Slider(document.querySelector('.carousel'), {
            inFrame: 2, // два элемента в кадре
            offset: 1, // смещать на один элемент
        });
    });
</script>

Поиск:
CSS • Frontend • HTML • JavaScript • Web-разработка • Изображение • Практика

Каталог оборудования

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Производители

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Функциональные группы

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

В этой статье мы будем делать самый простой слайдер на чистом JavaScript, и подойдёт статья только для самых начинающих JavaScrpt разработчиков.

Ещё есть статья где делаем более сложный и продвинутый слайдер: Делаем продвинутый слайдер на чистом javascript, прочитайте, если вам кажется слайдер из этой статьи кажется простым.

HTML:

Для начало нам нужно сделать подходящий HTML файл.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<!DOCTYPE html>

<html lang=«ru»>

<head>

    <meta charset=«UTF-8»>

    <title>Слайдер</title>

    <link rel=«stylesheet» href=«style.css»>

</head>

<body>

    <div class=«slides»>

        <img src=«img/portrait-1462944_1280.jpg» class=«block» alt=«»>

        <img src=«img/bled-1899264_1280.jpg» alt=«»>

        <img src=«img/cat-1455468_1280.jpg» alt=«»>

        <img src=«img/woman-1948939_1280.jpg» alt=«»>

        <img src=«img/france-2773030_1280.jpg» alt=«»>

    </div>

    <button class=«btnRight»>Right</button>

    <script src=«script.js» class=«btnRight»></script>

</body>

</html>

Объяснять досконально я не буду, так как, тут всё понятно и вы уже должны знать сам язык HTML, если уже разрабатываете на JavaScript, но скажу, что <div class="slides"> это контейнер который содержит в себе картинки.

CSS:

.slides {

    width: 1000px;

    height: 500px;

}

img {

    display: none;

}

.block {

    display: block;

    object-fit: cover;

    width: 100%;

    height: 100%;

}

Как видите файл вообще очень маленький, мы можем понять что все картинки будут скрыты, размер слайда будет, в ширину 1000 пикселей и в высоту 500 пикселе.

JavaScript:

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

// Берём кнопку вперёд

let btnRight = document.querySelector(«.btnRight»);

// Берём слайды

let slides = document.querySelectorAll(«img»);

// Объявляем переменную i

let i = 0;

// Объявляем событие нажатия на кнопку вперёд

btnRight.addEventListener(«click», function () {

    // Увеличиваем переменную i

    ++i

    // Условие если переменная i больше или равна количеству слайдов

    if (i >= slides.length) {

        // Удаляем класс block предыдущему слайду

        slides[i1].classList.remove(«block»);

        // Присваиваем переменной i ноль

        i = 0;

        // Добавляем класс block следующему слайду

        slides[i].classList.add(«block»);

    } else { // Иначе

        // Удаляем класс block предыдущему слайду

        slides[i1].classList.remove(«block»);

        // Добавляем класс block следующему слайду

        slides[i].classList.add(«block»);

    }

})

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

Вывод:

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

Подписываетесь на соц-сети:

Оценка:

Загрузка…

Также рекомендую:

Понравилась статья? Поделить с друзьями:
  • Как написать сладкову военкору
  • Как написать сладких снов подруге
  • Как написать сладких снов парню очень красиво
  • Как написать славянский алфавит
  • Как написать скрытый ник