Как создать простое полноэкранное слайд-шоу с помощью Vanilla JavaScript

100-7481901

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

Как обычно, чтоб получить первоначальное представление о том, что мы будем создавать, посмотрите на подобающую демонстрационную версию CodePen (поглядите наиболее крупную версию для наилучшего осознания):

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

1. Начните с разметки странички

Для сотворения слайд-шоу нам пригодится элемент с классом slideshow. В нем мы разместим перечень слайдов вкупе со стрелками навигации.

Любой слайд будет содержать фоновое изображение. Естественно, если для вас нравится, вы сможете добавлять доп контент.

По дефлоту отображается 1-ый слайд. Но мы можем настроить это поведение, прикрепив к подходящему слайду класс is-active. Вот нужная разметка:

    12345678910111213141516171819202122   

          

    •           
    •     

    •                      
    •     

    •                      
    •   

                                    …

    2. Обусловьте стили

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

    Сборка слайдов

    По дефлоту все слайды будут накладываться друг на друга. Они все будут укрыты, не считая активного. Чтоб сложить изображения, мы воспользуемся CSS Grid. Практически, я уже разглядел эту технику и ее достоинства по сопоставлению с обычным позиционированием в недавнешнем руководстве. Вот связанные стили:

    CSS .slideshow .slides { display: grid;

    }

    .slideshow .slide { grid-column: 1; grid-row: 1; opacity: 0; transition: opacity 0.4s;

    }

    .slideshow .slide.is-active { opacity: 1;

    }

    1234567891011121314 .slideshow .slides {  display: grid;} .slideshow .slide {  grid-column: 1;  grid-row: 1;  opacity: 0;  transition: opacity 0.4s;} .slideshow .slide.is-active {  opacity: 1;}

    Любой div снутри слайда получит собственный класс cover. Это конвертирует его фоновое изображение в полноэкранное фоновое изображение:

    CSS .cover { background-size: cover; background-repeat: no-repeat; background-position: center; height: 100vh;

    }

    123456 .cover {  background-size: cover;  background-repeat: no-repeat;  background-position: center;  height: 100vh;}

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

    1-4046524

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

    2-8742881

    По дефлоту цвет этих стрелок будет черным. Но при перемещении курсора снутри слайд-шоу их цвет должен поменяться и создать контраст по отношению к слайд-изображениям. Хитрость для сотворения этого эффекта заключается в добавлении к спанам mix-blend-mode: difference (либо exclusion) и filter: invert(1).

    3-6768744

    Дальше, стили для навигации:

    CSS .slideshow { cursor: none;

    }

    .slideshow .arrows { position: absolute; top: 0; left: 0; display: flex; width: 100%; height: 100%; overflow: hidden;

    }

    .slideshow .arrows .arrow { position: relative; width: 50%; cursor: inherit; visibility: hidden; overflow: inherit;

    }

    .slideshow .arrows .is-visible { visibility: visible;

    }

    .slideshow .arrows span { position: absolute; width: 72px; height: 72px; background-size: 72px 72px; mix-blend-mode: difference; filter: invert(1);

    }

    .slideshow .arrow-prev span { background-image: url(slider-prev-arrow.svg);

    }

    .slideshow .arrow-next span { background-image: url(slider-next-arrow.svg);

    }

    123456789101112131415161718192021222324252627282930313233343536373839404142 .slideshow {  cursor: none;} .slideshow .arrows {  position: absolute;  top: 0;  left: 0;  display: flex;  width: 100%;  height: 100%;  overflow: hidden;} .slideshow .arrows .arrow {  position: relative;  width: 50%;  cursor: inherit;  visibility: hidden;  overflow: inherit;} .slideshow .arrows .is-visible {  visibility: visible;} .slideshow .arrows span {  position: absolute;  width: 72px;  height: 72px;  background-size: 72px 72px;  mix-blend-mode: difference;  filter: invert(1);} .slideshow .arrow-prev span {  background-image: url(slider-prev-arrow.svg);}   .slideshow .arrow-next span {  background-image: url(slider-next-arrow.svg);}

    3. Добавьте JavaScript

    Давайте сейчас добавим к нашему слайд-шоу интерактивные функции! В этом примере в слайд-шоу будут включены три параметра по дефлоту, которые мы можем настроить, указав надлежащие настраиваемые атрибуты:

    Параметр: autoplay. Значение по дефлоту: false. Описание: Функция автопроигрывания.

    Параметр: autoplay-interval. Значение по дефлоту: 4000. Описание: Интервал времени меж переключением слайдов в миллисекундах.

    Параметр: stop-autoplay-on-hover. Значение по дефлоту: false. Описание: Приостановить режим автопроигрывания при наведении.

    Переменные

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

    Как TypeScript помогает вам стать лучшим разработчиком JavaScript

    JavaScript const slideshow = document.querySelector(“.slideshow”); const list = document.querySelector(“.slideshow .slides”); const btns = document.querySelectorAll(“.slideshow .arrows .arrow”); const prevBtn = document.querySelector(“.slideshow .arrow-prev”); const prevBtnChild = document.querySelector(“.slideshow .arrow-prev span”); const nextBtn = document.querySelector(“.slideshow .arrow-next”); const nextBtnChild = document.querySelector(“.slideshow .arrow-next span”); const main = document.querySelector(“main”); const autoplayInterval = parseInt(slideshow.dataset.autoplayInterval) || 4000; const isActive = “is-active”; const isVisible = “is-visible”;

    let intervalID;

    123456789101112 const slideshow = document.querySelector(“.slideshow”);const list = document.querySelector(“.slideshow .slides”);const btns = document.querySelectorAll(“.slideshow .arrows .arrow”);const prevBtn = document.querySelector(“.slideshow .arrow-prev”);const prevBtnChild = document.querySelector(“.slideshow .arrow-prev span”);const nextBtn = document.querySelector(“.slideshow .arrow-next”);const nextBtnChild = document.querySelector(“.slideshow .arrow-next span”);const main = document.querySelector(“main”);const autoplayInterval = parseInt(slideshow.dataset.autoplayInterval) || 4000;const isActive = “is-active”;const isVisible = “is-visible”;let intervalID;

    Инициализация вещей

    Когда все ресурсы странички будут готовы, мы вызовем функцию init.

    JavaScript window.addEventListener(“load”, init);

    1 window.addEventListener(“load”, init);

    Эта функция запустит четыре подфункции:

    JavaScript function init() { changeSlide(); autoPlay(); stopAutoPlayOnHover(); customizeArrows();

    }

    123456 function init() {  changeSlide();  autoPlay();  stopAutoPlayOnHover();  customizeArrows();}

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

    Цикл слайдов

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

    Берем экземпляр текущего активного слайда.

    Удаляем из активного слайда класс is-active.

    Проверяем, какая клавиша нажата. Если это клавиша «последующий», мы добавляем класс is-active к слайду, который следует сходу за активным слайдом. Если такового слайда нет, этот класс получит 1-ый слайд.

    Если же нажата клавиша «предшествующий», мы добавим класс is-active к предшествующему слайду от активного слайда. Если такового слайда нет, этот класс получит крайний слайд.

    Вот эта функция:

    JavaScript // variables here

    function changeSlide() { for (const btn of btns) { btn.addEventListener(“click”, e => { // 1 const activeSlide = document.querySelector(“.slide.is-active”); // 2 activeSlide.classList.remove(isActive); // 3 if (e.currentTarget === nextBtn) { activeSlide.nextElementSibling ? activeSlide.nextElementSibling.classList.add(isActive) : list.firstElementChild.classList.add(isActive); } else { // 4 activeSlide.previousElementSibling ? activeSlide.previousElementSibling.classList.add(isActive) : list.lastElementChild.classList.add(isActive); } }); }

    }

    1234567891011121314151617181920212223 // variables here function changeSlide() {  for (const btn of btns) {    btn.addEventListener(“click”, e => {      // 1      const activeSlide = document.querySelector(“.slide.is-active”);      // 2      activeSlide.classList.remove(isActive);      // 3      if (e.currentTarget === nextBtn) {        activeSlide.nextElementSibling          ? activeSlide.nextElementSibling.classList.add(isActive)          : list.firstElementChild.classList.add(isActive);      } else {        // 4        activeSlide.previousElementSibling          ? activeSlide.previousElementSibling.classList.add(isActive)          : list.lastElementChild.classList.add(isActive);      }    });  }}

    Автопроигрывание

    Функция autoplay будет отвечать за активацию режима автозапуска. По дефлоту мы должны вручную передвигаться по слайдам. Чтоб активировать автопроигрывание, мы добавим для слайд-шоу атрибут data-autoplay=»true».

    Мы также можем настроить интервал меж переключениями слайдов, определив data-autoplay-interval=»number» (по дефлоту 4000 мс) в качестве второго атрибута, к примеру:

    123   …

    Вот эта функция:

    JavaScript // variables here

    function autoPlay() { if (slideshow.dataset.autoplay === “true”) { intervalID = setInterval(() => { nextBtn.click(); }, autoplayInterval); }

    }

    123456789 // variables here function autoPlay() {  if (slideshow.dataset.autoplay === “true”) {    intervalID = setInterval(() => {      nextBtn.click();    }, autoplayInterval);  }}

    Остановка автопроигрывания

    Функция stopAutoplayOnHover будет отвечать за отключение режима автопроигрывания при наведении. Чтоб включить эту функцию, мы передадим атрибут data-stop-autoplay-on-hover=»true», к примеру, так:

    123   …

    Вот эта функция:

    JavaScript // variables here

    function stopAutoPlayOnHover() { if ( slideshow.dataset.autoplay === “true” && slideshow.dataset.stopAutoplayOnHover === “true” ) { slideshow.addEventListener(“mouseenter”, () => { clearInterval(intervalID);

    });

    // touch devices slideshow.addEventListener(“touchstart”, () => { clearInterval(intervalID); }); }

    }

    1234567891011121314151617 // variables here function stopAutoPlayOnHover() {  if (    slideshow.dataset.autoplay === “true” &&    slideshow.dataset.stopAutoplayOnHover === “true”  ) {    slideshow.addEventListener(“mouseenter”, () => {      clearInterval(intervalID);    });         // touch devices    slideshow.addEventListener(“touchstart”, () => {      clearInterval(intervalID);    });  }}

    Настройка стрелок

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

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

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

    JavaScript // variables here

    function customizeArrows() { slideshow.addEventListener(“mousemove”, mousemoveHandler); slideshow.addEventListener(“touchmove”, mousemoveHandler); slideshow.addEventListener(“mouseleave”, mouseleaveHandler); main.addEventListener(“touchstart”, mouseleaveHandler);

    }

    function mousemoveHandler(e) { const width = this.offsetWidth; const xPos = e.pageX; const yPos = e.pageY;

    const xPos2 = e.pageX – nextBtn.offsetLeft – nextBtnChild.offsetWidth;

    if (xPos > width / 2) { prevBtn.classList.remove(isVisible);

    nextBtn.classList.add(isVisible);

    nextBtnChild.style.left = `${xPos2}px`; nextBtnChild.style.top = `${yPos}px`; } else { nextBtn.classList.remove(isVisible);

    prevBtn.classList.add(isVisible);

    prevBtnChild.style.left = `${xPos}px`; prevBtnChild.style.top = `${yPos}px`; }

    }

    function mouseleaveHandler() { prevBtn.classList.remove(isVisible); nextBtn.classList.remove(isVisible);

    }

    12345678910111213141516171819202122232425262728293031323334 // variables here function customizeArrows() {  slideshow.addEventListener(“mousemove”, mousemoveHandler);  slideshow.addEventListener(“touchmove”, mousemoveHandler);  slideshow.addEventListener(“mouseleave”, mouseleaveHandler);  main.addEventListener(“touchstart”, mouseleaveHandler);} function mousemoveHandler(e) {  const width = this.offsetWidth;  const xPos = e.pageX;  const yPos = e.pageY;  const xPos2 = e.pageX – nextBtn.offsetLeft – nextBtnChild.offsetWidth;   if (xPos > width / 2) {    prevBtn.classList.remove(isVisible);    nextBtn.classList.add(isVisible);     nextBtnChild.style.left = `${xPos2}px`;    nextBtnChild.style.top = `${yPos}px`;  } else {    nextBtn.classList.remove(isVisible);    prevBtn.classList.add(isVisible);     prevBtnChild.style.left = `${xPos}px`;    prevBtnChild.style.top = `${yPos}px`;  }} function mouseleaveHandler() {  prevBtn.classList.remove(isVisible);  nextBtn.classList.remove(isVisible);}

    Заключение

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

    Создатель: George Martsoukos

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

    Источник