Создать слайд шоу используя javascript шаблоны. Фотолаборатория. Элементы управления Slidr

Обзор программ создания слайд-шоу Создание слайд-шоу для сайта

При создании слайд-шоу для размещения на сайте лучше всего воспользоваться готовыми программными решениями. На мой взгляд, оптимальный и самый простой вариант - использование jQuery, специальной бесплатной библиотеки скриптов (небольших программ на JavaScript ). В предыдущих статьях уже рассказывалось об этом замечательном инструменте веб-разработки. Например, смотрите статью Фотогалерея jQuery - просто и красиво! . Теперь применим jQuery для создания слайд-шоу на сайте, так называемого, слайдера.

Для этого воспользуемся плагином Slides , созданным программистом Натаном Салесом (Nathan Searles), техническим директором дизайн-студии "Бригада" ("The Brigade") в Портланде, штат Орегон, США. О другой его разработке рассказывалось в статье Фотогалерея для интернет магазина.

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



Установка слайд-шоу Slides

Как всегда, сначала создаем папку scripts на сайте. Затем надо скачать архив и распаковать его в созданную папку. В ней получится два скрипта jquery-1.8.3.min.js и jquery.cycle.all.min.js .

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




$(".slideshow").cycle({
fx: "fade"
});
});


.slideshow {
width: 200px;
height: 135px;
margin: auto;
}

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

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

Не рекомендуется использовать на одной странице несколько разных версий jQuery , чтобы они не конфликтовали друг с другом. При этом обязательно проверяйте работу плагинов с установленной версией jQuery , так как не все версии взаимозаменяемы.

Последний шаг - размещение изображений на странице. Здесь также всё просто. Размещаете изображения внутри тега или другого, для которого допустимо устанавливать ширину и высоту, и указываете его class="slideshow" . Для нашего примера HTML-код слайдера выглядит следующим образом:





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

Настройка параметров слайд-шоу Slides

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

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

1. Растворение (наш пример):

$(document).ready(function() {
$(".slideshow").cycle({
fx: "fade", //вид перехода
speed: 1000 , //скорость смены картинки
timeout: 1000 //длительность кадра
});
});

2. Перетасовывание:

$(document).ready(function() {
$(".slideshow").cycle({
fx: "shuffle",
sync: false,
speed: 500 ,
timeout: 5000
});
});

3. Зум:

$(document).ready(function() {
$(".slideshow").cycle({
fx: "zoom",
sync: false
});
});

4. Переворот по оси X или Y:

$(document).ready(function() {
$(".slideshow").cycle({
fx: "curtainX", // для поворота по оси Y - curtainY
sync: false
});
});

5. Сворачивание по вертикали:

$(document).ready(function() {
$(".slideshow").cycle({
fx: "turnDown", // направление можно задать turnUp, turnLeft, turnRight
sync: true
});
});

6. Скроллинг (смещение):

$(document).ready(function() {
$(".slideshow").cycle({
fx:"scrollDown", // направление смещения можно задать scrollUp, scrollLeft, scrollRight
sync: true
});
});

7. Наплыв справа:

$(document).ready(function() {
$(".slideshow").cycle({
fx: "cover
});
});

Иногда нужно разместить несколько вариантов слайд-шоу на одной странице сайта, как это сделано в данной статье. Для этого надо просто указывать разные классы для каждого варианта в строчке $(".slideshow").cycle({ (смотрите код в таблице выше), и не забудьте прописать в CSS размеры окна для каждого класса.

Если в слайдах содержатся только картинки, можно слегка поменять структуру:

Предыдущий Следующий

Не забудьте добавить осмысленное значение атрибуту alt.

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

... ... ... 1 2 3

Предыдущий Следующий 1 2 3

Отметим использование атрибутов «data» – некоторые слайд-шоу умеют вставлять картинки как фон, и эти атрибуты будут использованы в скрипте как места для связи фона и слайда.

Использование списков Семантически верным подходом будет использование элементов списка как слайдов. В этом случае структура будет такой:

Если порядок слайдов хорошо определён (к примеру, в презентации), можно использовать нумерованные списки

CSS Начнём со следующей структуры:

Предыдущий Следующий

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

Slider { width: 1024px; overflow: hidden; } .slider-wrapper { width: 9999px; height: 683px; position: relative; transition: left 500ms linear; }

Стили внутреннего враппера включают:

Большая ширина
- фиксированная высота, максимальная высота слайда
- position: relative, что позволит создать перемещение слайдов
- CSS transition left, что позволит сделать движение плавным. Для простоты мы не указали все префиксы. Для этого также можно использовать CSS transformations (вместе с translation).

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

Slide { float: left; position: relative; width: 1024px; height: 683px; }

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

Навигация осуществляется через кнопки “Предыдущий” и “Следующий”. Обнуляем их стили по умолчанию и назначаем свои:

Slider-nav { height: 40px; width: 100%; margin-top: 1.5em; } .slider-nav button { border: none; display: block; width: 40px; height: 40px; cursor: pointer; text-indent: -9999em; background-color: transparent; background-repeat: no-repeat; } .slider-nav button.slider-previous { float: left; background-image: url(previous.png); } .slider-nav button.slider-next { float: right; background-image: url(next.png); }

При использовании ссылок на страницы вместо кнопок можно сделать следующие стили:

Slider-nav { text-align: center; margin-top: 1.5em; } .slider-nav a { display: inline-block; text-decoration: none; border: 1px solid #ddd; color: #444; width: 2em; height: 2em; line-height: 2; text-align: center; } .slider-nav a.current { border-color: #000; color: #000; font-weight: bold; }

Эти классы будут назначены из скрипта динамически.

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

Slider { width: 1024px; margin: 2em auto; } .slider-wrapper { width: 100%; height: 683px; position: relative; /* Создаёт контекст для абсолютного позиционирования */ } .slide { position: absolute; /* Абсолютное позиционирование всех слайдов */ width: 100%; height: 100%; opacity: 0; /* Все слайды скрыты */ transition: opacity 500ms linear; } /* Изначально виден только первый */ .slider-wrapper >
Для скрытия слайдов мы используем свойство opacity, поскольку программы для чтения данных с экрана пропускают содержимое элементов, у которых установлен display: none (см. CSS in Action: Invisible Content Just for Screen Reader Users).

Благодаря контекстному позиционированию CSS мы создали "пачку" слайдов, где последний слайд в исходнике оказывается впереди других. Но нам не это нужно. Для сохранения порядка слайдов нам надо спрятать все слайды, кроме первого.

JS задействует CSS transition, меняя значение свойства opacity у текущего слайда, и обнуляя это значение у всех остальных.

Код на JavaScriptСлайд-шоу без разбивки на страницы Слайд-шоу без разбивки на страницы работают по нажатию кнопок “Следующий” и “Предыдущий”. Их можно рассматривать как операторы инкремента и декремента. Всегда есть указатель (или курсор), который будет увеличен или уменьшен каждый раз по нажатию на кнопки. Начальное его значение 0, а цель – выбирать текущий слайд так же, как выбираются элементы массива.

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

Вместе с указателем мы используем метод jQuery .eq() для получения текущего слайда. На чистом JS это выглядит так:

Function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.slides = this.el.querySelectorAll(".slide"); //... }, _slideTo: function(pointer) { var currentSlide = this.slides; //... } };

Помните - NodeList использует индексы так же, как массив. Ещё один способ выбрать текущий слайд – селекторы CSS3:

Slideshow.prototype = { init: function() { //... }, _slideTo: function(pointer) { var n = pointer + 1; var currentSlide = this.el.querySelector(".slide:nth-child(" + n + ")"); //... } };

Селектор CSS3:nth-child() считает элементы с 1, поэтому нужно добавить единичку к указателю. После выбора слайда его родительский контейнер надо сдвинуть справа налево. В jQuery можно использовать метод.animate():

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", slides: ".slide", //... speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $(options.wrapper, element). animate({ left: - $currentSlide.position().left }, options.speed, options.easing); }; //... }; })(jQuery);

В обычном JS нет метода.animate(), поэтому мы используем переходы CSS:

Slider-wrapper { position: relative; // обязательно transition: left 500ms linear; }

Теперь можно менять свойство left динамически через объект style:

Function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); //... }, _slideTo: function(pointer) { var currentSlide = this.slides; this.wrapper.style.left = "-" + currentSlide.offsetLeft + "px"; } };

Теперь надо сделать событие клика для каждого элемента управления. В jQuery можно взять метод.on(), а в чистом JS - метод addEventListener().

Также надо проверять, не достиг ли указатель границ списка – 0 для “Предыдущий” и общего количества слайдов для “Следующий”. В каждом случае надо прятать соответствующую кнопку:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", slides: ".slide", previous: ".slider-previous", next: ".slider-next", //... speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $(options.wrapper, element). animate({ left: - $currentSlide.position().left }, options.speed, options.easing); }; return this.each(function() { var $element = $(this), $previous = $(options.previous, $element), $next = $(options.next, $element), index = 0, total = $(options.slides).length; $next.on("click", function() { index++; $previous.show(); if(index == total - 1) { index = total - 1; $next.hide(); } slideTo(index, $element); }); $previous.on("click", function() { index--; $next.show(); if(index == 0) { index = 0; $previous.hide(); } slideTo(index, $element); }); }); }; })(jQuery);

А на чистом JS это выглядит так:

Function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); this.previous = this.el.querySelector(".slider-previous"); this.next = this.el.querySelector(".slider-next"); this.index = 0; this.total = this.slides.length; this.actions(); }, _slideTo: function(pointer) { var currentSlide = this.slides; this.wrapper.style.left = "-" + currentSlide.offsetLeft + "px"; }, actions: function() { var self = this; self.next.addEventListener("click", function() { self.index++; self.previous.style.display = "block"; if(self.index == self.total - 1) { self.index = self.total - 1; self.next.style.display = "none"; } self._slideTo(self.index); }, false); self.previous.addEventListener("click", function() { self.index--; self.next.style.display = "block"; if(self.index == 0) { self.index = 0; self.previous.style.display = "none"; } self._slideTo(self.index); }, false); } };

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

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", slides: ".slide", nav: ".slider-nav", speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $(options.wrapper, element). animate({ left: - $currentSlide.position().left }, options.speed, options.easing); }; return this.each(function() { var $element = $(this), $navigationLinks = $("a", options.nav); $navigationLinks.on("click", function(e) { e.preventDefault(); var $a = $(this), $slide = $($a.attr("href")); slideTo($slide, $element); $a.addClass("current").siblings(). removeClass("current"); }); }); }; })(jQuery);

В этом случае каждый анкор соответствует ID определённого слайда. В чистом JS можно использовать как его, так и атрибут data, хранящий числовой индекс слайдов внутри NodeList:

Function Slider(element) { 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.navigate(); }, navigate: function() { for (var i = 0; i < this.links.length; ++i) { var link = this.links[i]; this.slide(link); } }, slide: function(element) { var self = this; element.addEventListener("click", function(e) { e.preventDefault(); var a = this; self.setCurrentLink(a); var index = parseInt(a.getAttribute("data-slide"), 10) + 1; var currentSlide = self.el.querySelector(".slide:nth-child(" + index + ")"); self.wrapper.style.left = "-" + currentSlide.offsetLeft + "px"; }, false); }, setCurrentLink: function(link) { var parent = link.parentNode; var a = parent.querySelectorAll("a"); link.className = "current"; for (var j = 0; j < a.length; ++j) { var cur = a[j]; if (cur !== link) { cur.className = ""; } } } };

Начиная с IE10 можно управлять классами через classList:

Link.classList.add("current");

А с IE11 атрибуты data можно получать через свойство dataset:

Var index = parseInt(a.dataset.slide, 10) + 1;

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

Синхронизировать это можно через номерной индекс каждой ссылки в DOM. Один линк – один слайд, поэтому их индексы будут 0, 1, 2 и т.д.

На jQuery код будет такой:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ //... pagination: ".slider-pagination", //... }, options); $.fn.slideshow.index = 0; return this.each(function() { var $element = $(this), //... $pagination = $(options.pagination, $element), $paginationLinks = $("a", $pagination), //... $paginationLinks.on("click", function(e) { e.preventDefault(); var $a = $(this), elemIndex = $a.index(); // DOM numerical index $.fn.slideshow.index = elemIndex; if($.fn.slideshow.index > 0) { $previous.show(); } else { $previous.hide(); } if($.fn.slideshow.index == total - 1) { $.fn.slideshow.index = total - 1; $next.hide(); } else { $next.show(); } slideTo($.fn.slideshow.index, $element); $a.addClass("current"). siblings().removeClass("current"); }); }); }; //... })(jQuery);

Сразу видно, что изменилась видимость курсора – теперь индекс объявлен как свойство объекта слайд-шоу. Таким образом мы избегаем проблем с областью видимости, которые могут быть созданы обратными вызовами в jQuery. Теперь курсор доступен везде, и даже вне пространства имён плагина, поскольку он объявлен как публичное свойство объекта slideshow.

Метод.index() даёт числовой индекс каждой ссылки.

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

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); this.previous = this.el.querySelector(".slider-previous"); this.next = this.el.querySelector(".slider-next"); this.navigationLinks = this.el.querySelectorAll(".slider-pagination a"); this.index = 0; this.total = this.slides.length; this.setup(); this.actions(); }, //... setup: function() { var self = this; //... for(var k = 0; k < self.navigationLinks.length; ++k) { var pagLink = self.navigationLinks[k]; pagLink.setAttribute("data-index", k); // Или pagLink.dataset.index = k; } }, //... }; })();

Теперь мы можем соединить наши процедуры со ссылками и использовать только что созданные атрибуты данных:

Actions: function() { var self = this; //... for(var i = 0; i < self.navigationLinks.length; ++i) { var a = self.navigationLinks[i]; a.addEventListener("click", function(e) { e.preventDefault(); var n = parseInt(this.getAttribute("data-index"), 10); // Или var n = parseInt(this.dataset.index, 10); self.index = n; if(self.index == 0) { self.index = 0; self.previous.style.display = "none"; } if(self.index > 0) { self.previous.style.display = "block"; } if(self.index == self.total - 1) { self.index = self.total - 1; self.next.style.display = "none"; } else { self.next.style.display = "block"; } self._slideTo(self.index); self._highlightCurrentLink(this); }, false); } }

Разбираемся с размерами Вернёмся-ка к следующему правилу CSS:

Slider-wrapper { width: 9999px; height: 683px; position: relative; transition: left 500ms linear; }

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

На jQuery это просто:

// Слайд-шоу на всю ширину return this.each(function() { var $element = $(this), total = $(options.slides).length; //... $(options.slides, $element).width($(window).width()); $(options.wrapper, $element).width($(window).width() * total); //... });

Берём ширину окна и задаём ширину каждого слайда. Общая ширина внутреннего враппера получается перемножением ширины окна и количества слайдов.

// Слайд-шоу фиксированной ширины return this.each(function() { var $element = $(this), total = $(options.slides).length; //... $(options.wrapper, $element).width($(options.slides).eq(0).width() * total); //... });

Здесь начальная ширина задана шириной каждого слайда. Нужно только задать общую ширину враппера.

Теперь внутренний контейнер достаточно широк. На чистом JS это делается примерно так же:

// Слайд-шоу на всю ширину Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); //... this.total = this.slides.length; this.setDimensions(); this.actions(); }, setDimensions: function() { var self = this; // Viewport"s width var winWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var wrapperWidth = winWidth * self.total; for(var i = 0; i < self.total; ++i) { var slide = self.slides[i]; slide.style.width = winWidth + "px"; } self.wrapper.style.width = wrapperWidth + "px"; }, //... }; // Слайд-шоу фиксированной ширины Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); //... this.total = this.slides.length; this.setDimensions(); this.actions(); }, setDimensions: function() { var self = this; var slideWidth = self.slides.offsetWidth; // Single slide"s width var wrapperWidth = slideWidth * self.total; self.wrapper.style.width = wrapperWidth + "px"; }, //... };

Эффекты исчезновения Эффекты исчезновения (fade) часто используются в слайд-шоу. Текущий слайд исчезает, и появляется следующий. У jQuery есть методы fadeIn() и fadeOut(), которые работают как со свойством opacity, так и с display, поэтому элемент удаляется из страницы по завершению анимации (display:none).

В чистом JS лучше всего работать со свойством opacity и использовать стек позиционирования CSS. Тогда изначально слайд будет видимым (opacity: 1), а другие - спрятаны (opacity:0).

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

Slider { width: 100%; overflow: hidden; position: relative; height: 400px; } .slider-wrapper { width: 100%; height: 100%; position: relative; } .slide { position: absolute; width: 100%; height: 100%; opacity: 0; } .slider-wrapper > .slide:first-child { opacity: 1; }

В чистом JS необходимо зарегистрировать переход CSS каждого слайда:

Slide { float: left; position: absolute; width: 100%; height: 100%; opacity: 0; transition: opacity 500ms linear; }

С jQuery для использования методов fadeIn() и fadeOut() надо менять opacity и display:

Slide { float: left; position: absolute; width: 100%; height: 100%; display: none; } .slider-wrapper > .slide:first-child { display: block; }

В jQuery код следующий:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", previous: ".slider-previous", next: ".slider-next", slides: ".slide", nav: ".slider-nav", speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $currentSlide. animate({ opacity: 1 }, options.speed, options.easing). siblings(options.slides). css("opacity", 0); }; //... }; })(jQuery);

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

В JavaScript это будет:

Slideshow.prototype = { //... _slideTo: function(slide) { var currentSlide = this.slides; currentSlide.style.opacity = 1; for(var i = 0; i < this.slides.length; i++) { var slide = this.slides[i]; if(slide !== currentSlide) { slide.style.opacity = 0; } } }, //... };

Медийные элементы: видео Мы можем включать видео в слайд-шоу. Вот пример слайд-шоу с видео от Vimeo:

Видео включаются через iframe. Это такой же заменяемый inline-block, как и картинка. Заменяемый – потому, что содержимое взято из внешнего источника.

Чтобы создать полностраничное слайд-шоу, надо поменять стили следующим образом:

Html, body { margin: 0; padding: 0; height: 100%; min-height: 100%; /* Высота должна быть со всю страницу */ } .slider { width: 100%; overflow: hidden; height: 100%; min-height: 100%; /* Высота и ширина на полную */ position: absolute; /* Абсолютное позиционирование */ } .slider-wrapper { width: 100%; height: 100%; /* Высота и ширина на полную */ position: relative; } .slide { float: left; position: absolute; width: 100%; height: 100%; } .slide iframe { display: block; /* Блочный элемент */ position: absolute; /* Абсолютное позиционирование */ width: 100%; height: 100%; /* Высота и ширина на полную */ }

Автоматические слайд-шоу Автоматические слайд-шоу используют таймеры. При каждом обратном вызове функции по таймеру setInterval() курсор будет увеличиваться на 1 и таким образом будет выбираться следующий слайд.

Когда курсор достигнет максимального количества слайдов, его надо обнулить.

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

(function($) { $.fn.slideshow = function(options) { options = $.extend({ slides: ".slide", speed: 3000, easing: "linear" }, options); var timer = null; // Таймер var index = 0; // Курсор var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $currentSlide.stop(true, true). animate({ opacity: 1 }, options.speed, options.easing). siblings(options.slides). css("opacity", 0); }; var autoSlide = function(element) { // Инициализируем последовательность timer = setInterval(function() { index++; // Увеличим курсор на 1 if(index == $(options.slides, element).length) { index = 0; // Обнулим курсор } slideTo(index, element); }, options.speed); // Тот же интервал, что и в методе.animate() }; var startStop = function(element) { element.hover(function() { // Останавливаем анимацию clearInterval(timer); timer = null; }, function() { autoSlide(element); // Возобновляем анимацию }); }; return this.each(function() { var $element = $(this); autoSlide($element); startStop($element); }); }; })(jQuery);

Оба параметра метода.stop() установлены в true, т.к. нам не нужно создавать очередь анимации из нашей последовательности.

На чистом JS код становится проще. Регистрируем переход CSS для каждого слайда с определённой длительности:

Slide { transition: opacity 3s linear; /* 3 секунды = 3000 миллисекунд */ }

И код будет следующим:

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.slides = this.el.querySelectorAll(".slide"); this.index = 0; // Курсор this.timer = null; // Таймер this.action(); this.stopStart(); }, _slideTo: function(slide) { var currentSlide = this.slides; currentSlide.style.opacity = 1; for(var i = 0; i < this.slides.length; i++) { var slide = this.slides[i]; if(slide !== currentSlide) { slide.style.opacity = 0; } } }, action: function() { var self = this; // Initializes the sequence self.timer = setInterval(function() { self.index++; // Увеличим курсор на 1 if(self.index == self.slides.length) { self.index = 0; // Обнулим курсор } self._slideTo(self.index); }, 3000); // Тот же интервал, что и у перехода CSS }, stopStart: function() { var self = this; // Останавливаем анимацию self.el.addEventListener("mouseover", function() { clearInterval(self.timer); self.timer = null; }, false); // Возобновляем анимацию self.el.addEventListener("mouseout", function() { self.action(); }, false); } }; })();

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

Для этого мы обратимся к свойству keyCode объекта event. Оно возвращает код нажатой клавиши (список кодов).

Те события, что мы прикрепляли на кнопки "Предыдущий" и "Следующий", теперь можно прикрепить на клавиши "влево" и "вправо". jQuery:

$("body").on("keydown", function(e) { var code = e.keyCode; if(code == 39) { // Стрелка влево $next.trigger("click"); } if(code == 37) { // Стрелка вправо $previous.trigger("click"); } });

На чистом JS вместо простого метода.trigger() придётся пользоваться dispatchEvent():

Document.body.addEventListener("keydown", function(e) { var code = e.keyCode; var evt = new MouseEvent("click"); // нажатие мыши if(code == 39) { // Стрелка влево self.next.dispatchEvent(evt); } if(code == 37) { // Стрелка вправо self.previous.dispatchEvent(evt); } }, false);

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

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

В jQuery можно создать обратный вызов так:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ //... callback: function() {} }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $currentSlide. animate({ opacity: 1 }, options.speed, options.easing, // Обратный вызов для текущего слайда options.callback($currentSlide)). siblings(options.slides). css("opacity", 0); }; //... }; })(jQuery);

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

$(function() { $("#main-slider").slideshow({ callback: function(slide) { var $wrapper = slide.parent(); // Показывает текущую подпись и прячет остальные $wrapper.find(".slide-caption").hide(); slide.find(".slide-caption").show("slow"); } }); });

На чистом JS:

(function() { function Slideshow(element, callback) { this.callback = callback || function() {}; // Our callback this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { //... this.slides = this.el.querySelectorAll(".slide"); //... //... }, _slideTo: function(slide) { var self = this; var currentSlide = self.slides; currentSlide.style.opacity = 1; for(var i = 0; i < self.slides.length; i++) { var slide = self.slides[i]; if(slide !== currentSlide) { slide.style.opacity = 0; } } setTimeout(self.callback(currentSlide), 500); // Вызывает функцию по окончанию перехода } }; // })();

Функция обратного вызова определена как второй параметр конструктора. Использовать её можно так:

Document.addEventListener("DOMContentLoaded", function() { var slider = new Slideshow("#main-slider", function(slide) { var wrapper = slide.parentNode; // Показывает текущую подпись и прячет остальные var allSlides = wrapper.querySelectorAll(".slide"); var caption = slide.querySelector(".slide-caption"); caption.classList.add("visible"); for(var i = 0; i < allSlides.length; ++i) { var sld = allSlides[i]; var cpt = sld.querySelector(".slide-caption"); if(sld !== slide) { cpt.classList.remove("visible"); } } }); });

Внешние API Пока наш сценарий работы прост: все слайды уже есть в документе. Если нам надо вставлять в него данные снаружи (YouTube, Vimeo, Flickr), нам нужно на лету заполнять слайды по мере получения внешнего контента.

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

Предыдущий Следующий

Это может быть gif или анимация на чистом CSS:

#spinner { border-radius: 50%; border: 2px solid #000; height: 80px; width: 80px; position: absolute; top: 50%; left: 50%; margin: -40px 0 0 -40px; } #spinner:after { content: ""; position: absolute; background-color: #000; top:2px; left: 48%; height: 38px; width: 2px; border-radius: 5px; -webkit-transform-origin: 50% 97%; transform-origin: 50% 97%; -webkit-animation: angular 1s linear infinite; animation: angular 1s linear infinite; } @-webkit-keyframes angular { 0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(360deg);} } @keyframes angular { 0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);} } #spinner:before { content: ""; position: absolute; background-color: #000; top:6px; left: 48%; height: 35px; width: 2px; border-radius: 5px; -webkit-transform-origin: 50% 94%; transform-origin: 50% 94%; -webkit-animation: ptangular 6s linear infinite; animation: ptangular 6s linear infinite; } @-webkit-keyframes ptangular { 0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(360deg);} } @keyframes ptangular { 0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);} }

Шаги будут такие:
- запросить данные извне
- спрятать загрузчик
- разобрать данные
- построить HTML
- вывести слайд-шоу
- обрабатывать слайд-шоу

Допустим, мы выбираем самые свежие видео пользователя с YouTube. jQuery:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", //... loader: "#spinner", //... limit: 5, username: "learncodeacademy" }, options); //... var getVideos = function() { // Получить видео с YouTube var ytURL = "https://gdata.youtube.com/feeds/api/videos?alt=json&author=" + options.username + "&max-results=" + options.limit; $.getJSON(ytURL, function(videos) { // Получаем видео как объект JSON $(options.loader).hide(); // Прячем загрузчик var entries = videos.feed.entry; var html = ""; for(var i = 0; i < entries.length; ++i) { // Разбираем данные и строим строку HTML var entry = entries[i]; var idURL = entry.id.$t; var idVideo = idURL.replace("http://gdata.youtube.com/feeds/api/videos/", ""); var ytEmbedURL = "https://www.youtube.com/embed/" + idVideo + "?rel=0&showinfo=0&controls=0"; html += ""; html += ""; html += ""; } $(options.wrapper).html(html); // Выведем слайд-шоу }); }; return this.each(function() { //... getVideos(); // Обрабатываем слайд-шоу }); }; })(jQuery);

На чистом JavaScript есть лишний шаг – создание метода получения JSON:

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.loader = this.el.querySelector("#spinner"); //... this.limit = 5; this.username = "learncodeacademy"; }, _getJSON: function(url, callback) { callback = callback || function() {}; var request = new XMLHttpRequest(); request.open("GET", url, true); request.send(null); request.onreadystatechange = function() { if (request.status == 200 && request.readyState == 4) { var data = JSON.parse(request.responseText); // JSON object callback(data); } else { console.log(request.status); } }; }, //... }; })();

Затем процедуры получаются схожие:

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.loader = this.el.querySelector("#spinner"); //... this.limit = 5; this.username = "learncodeacademy"; this.actions(); }, _getJSON: function(url, callback) { callback = callback || function() {}; var request = new XMLHttpRequest(); request.open("GET", url, true); request.send(null); request.onreadystatechange = function() { if (request.status == 200 && request.readyState == 4) { var data = JSON.parse(request.responseText); // JSON object callback(data); } else { console.log(request.status); } }; }, //... getVideos: function() { var self = this; // Получить видео YouTube var ytURL = "https://gdata.youtube.com/feeds/api/videos?alt=json&author=" + self.username + "&max-results=" + self.limit; self._getJSON(ytURL, function(videos) { // Получаем видео как объект JSON var entries = videos.feed.entry; var html = ""; self.loader.style.display = "none"; // Прячем загрузчик for(var i = 0; i < entries.length; ++i) { // Разбираем данные и строим строку HTML var entry = entries[i]; var idURL = entry.id.$t; var idVideo = idURL.replace("http://gdata.youtube.com/feeds/api/videos/", ""); var ytEmbedURL = "https://www.youtube.com/embed/" + idVideo + "?rel=0&showinfo=0&controls=0"; html += ""; html += ""; html += ""; } self.wrapper.innerHTML = html; // Выводим слайд-шоу }); }, actions: function() { var self = this; self.getVideos(); // Обрабатываем слайд-шоу } }; })(); Добавить метки

Если в слайдах содержатся только картинки, можно слегка поменять структуру:

Предыдущий Следующий

Не забудьте добавить осмысленное значение атрибуту alt.

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

... ... ... 1 2 3

Предыдущий Следующий 1 2 3

Отметим использование атрибутов «data» – некоторые слайд-шоу умеют вставлять картинки как фон, и эти атрибуты будут использованы в скрипте как места для связи фона и слайда.

Использование списков Семантически верным подходом будет использование элементов списка как слайдов. В этом случае структура будет такой:

Если порядок слайдов хорошо определён (к примеру, в презентации), можно использовать нумерованные списки

CSS Начнём со следующей структуры:

Предыдущий Следующий

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

Slider { width: 1024px; overflow: hidden; } .slider-wrapper { width: 9999px; height: 683px; position: relative; transition: left 500ms linear; }

Стили внутреннего враппера включают:

Большая ширина
- фиксированная высота, максимальная высота слайда
- position: relative, что позволит создать перемещение слайдов
- CSS transition left, что позволит сделать движение плавным. Для простоты мы не указали все префиксы. Для этого также можно использовать CSS transformations (вместе с translation).

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

Slide { float: left; position: relative; width: 1024px; height: 683px; }

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

Навигация осуществляется через кнопки “Предыдущий” и “Следующий”. Обнуляем их стили по умолчанию и назначаем свои:

Slider-nav { height: 40px; width: 100%; margin-top: 1.5em; } .slider-nav button { border: none; display: block; width: 40px; height: 40px; cursor: pointer; text-indent: -9999em; background-color: transparent; background-repeat: no-repeat; } .slider-nav button.slider-previous { float: left; background-image: url(previous.png); } .slider-nav button.slider-next { float: right; background-image: url(next.png); }

При использовании ссылок на страницы вместо кнопок можно сделать следующие стили:

Slider-nav { text-align: center; margin-top: 1.5em; } .slider-nav a { display: inline-block; text-decoration: none; border: 1px solid #ddd; color: #444; width: 2em; height: 2em; line-height: 2; text-align: center; } .slider-nav a.current { border-color: #000; color: #000; font-weight: bold; }

Эти классы будут назначены из скрипта динамически.

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

Slider { width: 1024px; margin: 2em auto; } .slider-wrapper { width: 100%; height: 683px; position: relative; /* Создаёт контекст для абсолютного позиционирования */ } .slide { position: absolute; /* Абсолютное позиционирование всех слайдов */ width: 100%; height: 100%; opacity: 0; /* Все слайды скрыты */ transition: opacity 500ms linear; } /* Изначально виден только первый */ .slider-wrapper >
Для скрытия слайдов мы используем свойство opacity, поскольку программы для чтения данных с экрана пропускают содержимое элементов, у которых установлен display: none (см. CSS in Action: Invisible Content Just for Screen Reader Users).

Благодаря контекстному позиционированию CSS мы создали "пачку" слайдов, где последний слайд в исходнике оказывается впереди других. Но нам не это нужно. Для сохранения порядка слайдов нам надо спрятать все слайды, кроме первого.

JS задействует CSS transition, меняя значение свойства opacity у текущего слайда, и обнуляя это значение у всех остальных.

Код на JavaScriptСлайд-шоу без разбивки на страницы Слайд-шоу без разбивки на страницы работают по нажатию кнопок “Следующий” и “Предыдущий”. Их можно рассматривать как операторы инкремента и декремента. Всегда есть указатель (или курсор), который будет увеличен или уменьшен каждый раз по нажатию на кнопки. Начальное его значение 0, а цель – выбирать текущий слайд так же, как выбираются элементы массива.

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

Вместе с указателем мы используем метод jQuery .eq() для получения текущего слайда. На чистом JS это выглядит так:

Function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.slides = this.el.querySelectorAll(".slide"); //... }, _slideTo: function(pointer) { var currentSlide = this.slides; //... } };

Помните - NodeList использует индексы так же, как массив. Ещё один способ выбрать текущий слайд – селекторы CSS3:

Slideshow.prototype = { init: function() { //... }, _slideTo: function(pointer) { var n = pointer + 1; var currentSlide = this.el.querySelector(".slide:nth-child(" + n + ")"); //... } };

Селектор CSS3:nth-child() считает элементы с 1, поэтому нужно добавить единичку к указателю. После выбора слайда его родительский контейнер надо сдвинуть справа налево. В jQuery можно использовать метод.animate():

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", slides: ".slide", //... speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $(options.wrapper, element). animate({ left: - $currentSlide.position().left }, options.speed, options.easing); }; //... }; })(jQuery);

В обычном JS нет метода.animate(), поэтому мы используем переходы CSS:

Slider-wrapper { position: relative; // обязательно transition: left 500ms linear; }

Теперь можно менять свойство left динамически через объект style:

Function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); //... }, _slideTo: function(pointer) { var currentSlide = this.slides; this.wrapper.style.left = "-" + currentSlide.offsetLeft + "px"; } };

Теперь надо сделать событие клика для каждого элемента управления. В jQuery можно взять метод.on(), а в чистом JS - метод addEventListener().

Также надо проверять, не достиг ли указатель границ списка – 0 для “Предыдущий” и общего количества слайдов для “Следующий”. В каждом случае надо прятать соответствующую кнопку:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", slides: ".slide", previous: ".slider-previous", next: ".slider-next", //... speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $(options.wrapper, element). animate({ left: - $currentSlide.position().left }, options.speed, options.easing); }; return this.each(function() { var $element = $(this), $previous = $(options.previous, $element), $next = $(options.next, $element), index = 0, total = $(options.slides).length; $next.on("click", function() { index++; $previous.show(); if(index == total - 1) { index = total - 1; $next.hide(); } slideTo(index, $element); }); $previous.on("click", function() { index--; $next.show(); if(index == 0) { index = 0; $previous.hide(); } slideTo(index, $element); }); }); }; })(jQuery);

А на чистом JS это выглядит так:

Function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); this.previous = this.el.querySelector(".slider-previous"); this.next = this.el.querySelector(".slider-next"); this.index = 0; this.total = this.slides.length; this.actions(); }, _slideTo: function(pointer) { var currentSlide = this.slides; this.wrapper.style.left = "-" + currentSlide.offsetLeft + "px"; }, actions: function() { var self = this; self.next.addEventListener("click", function() { self.index++; self.previous.style.display = "block"; if(self.index == self.total - 1) { self.index = self.total - 1; self.next.style.display = "none"; } self._slideTo(self.index); }, false); self.previous.addEventListener("click", function() { self.index--; self.next.style.display = "block"; if(self.index == 0) { self.index = 0; self.previous.style.display = "none"; } self._slideTo(self.index); }, false); } };

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

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", slides: ".slide", nav: ".slider-nav", speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $(options.wrapper, element). animate({ left: - $currentSlide.position().left }, options.speed, options.easing); }; return this.each(function() { var $element = $(this), $navigationLinks = $("a", options.nav); $navigationLinks.on("click", function(e) { e.preventDefault(); var $a = $(this), $slide = $($a.attr("href")); slideTo($slide, $element); $a.addClass("current").siblings(). removeClass("current"); }); }); }; })(jQuery);

В этом случае каждый анкор соответствует ID определённого слайда. В чистом JS можно использовать как его, так и атрибут data, хранящий числовой индекс слайдов внутри NodeList:

Function Slider(element) { 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.navigate(); }, navigate: function() { for (var i = 0; i < this.links.length; ++i) { var link = this.links[i]; this.slide(link); } }, slide: function(element) { var self = this; element.addEventListener("click", function(e) { e.preventDefault(); var a = this; self.setCurrentLink(a); var index = parseInt(a.getAttribute("data-slide"), 10) + 1; var currentSlide = self.el.querySelector(".slide:nth-child(" + index + ")"); self.wrapper.style.left = "-" + currentSlide.offsetLeft + "px"; }, false); }, setCurrentLink: function(link) { var parent = link.parentNode; var a = parent.querySelectorAll("a"); link.className = "current"; for (var j = 0; j < a.length; ++j) { var cur = a[j]; if (cur !== link) { cur.className = ""; } } } };

Начиная с IE10 можно управлять классами через classList:

Link.classList.add("current");

А с IE11 атрибуты data можно получать через свойство dataset:

Var index = parseInt(a.dataset.slide, 10) + 1;

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

Синхронизировать это можно через номерной индекс каждой ссылки в DOM. Один линк – один слайд, поэтому их индексы будут 0, 1, 2 и т.д.

На jQuery код будет такой:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ //... pagination: ".slider-pagination", //... }, options); $.fn.slideshow.index = 0; return this.each(function() { var $element = $(this), //... $pagination = $(options.pagination, $element), $paginationLinks = $("a", $pagination), //... $paginationLinks.on("click", function(e) { e.preventDefault(); var $a = $(this), elemIndex = $a.index(); // DOM numerical index $.fn.slideshow.index = elemIndex; if($.fn.slideshow.index > 0) { $previous.show(); } else { $previous.hide(); } if($.fn.slideshow.index == total - 1) { $.fn.slideshow.index = total - 1; $next.hide(); } else { $next.show(); } slideTo($.fn.slideshow.index, $element); $a.addClass("current"). siblings().removeClass("current"); }); }); }; //... })(jQuery);

Сразу видно, что изменилась видимость курсора – теперь индекс объявлен как свойство объекта слайд-шоу. Таким образом мы избегаем проблем с областью видимости, которые могут быть созданы обратными вызовами в jQuery. Теперь курсор доступен везде, и даже вне пространства имён плагина, поскольку он объявлен как публичное свойство объекта slideshow.

Метод.index() даёт числовой индекс каждой ссылки.

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

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); this.previous = this.el.querySelector(".slider-previous"); this.next = this.el.querySelector(".slider-next"); this.navigationLinks = this.el.querySelectorAll(".slider-pagination a"); this.index = 0; this.total = this.slides.length; this.setup(); this.actions(); }, //... setup: function() { var self = this; //... for(var k = 0; k < self.navigationLinks.length; ++k) { var pagLink = self.navigationLinks[k]; pagLink.setAttribute("data-index", k); // Или pagLink.dataset.index = k; } }, //... }; })();

Теперь мы можем соединить наши процедуры со ссылками и использовать только что созданные атрибуты данных:

Actions: function() { var self = this; //... for(var i = 0; i < self.navigationLinks.length; ++i) { var a = self.navigationLinks[i]; a.addEventListener("click", function(e) { e.preventDefault(); var n = parseInt(this.getAttribute("data-index"), 10); // Или var n = parseInt(this.dataset.index, 10); self.index = n; if(self.index == 0) { self.index = 0; self.previous.style.display = "none"; } if(self.index > 0) { self.previous.style.display = "block"; } if(self.index == self.total - 1) { self.index = self.total - 1; self.next.style.display = "none"; } else { self.next.style.display = "block"; } self._slideTo(self.index); self._highlightCurrentLink(this); }, false); } }

Разбираемся с размерами Вернёмся-ка к следующему правилу CSS:

Slider-wrapper { width: 9999px; height: 683px; position: relative; transition: left 500ms linear; }

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

На jQuery это просто:

// Слайд-шоу на всю ширину return this.each(function() { var $element = $(this), total = $(options.slides).length; //... $(options.slides, $element).width($(window).width()); $(options.wrapper, $element).width($(window).width() * total); //... });

Берём ширину окна и задаём ширину каждого слайда. Общая ширина внутреннего враппера получается перемножением ширины окна и количества слайдов.

// Слайд-шоу фиксированной ширины return this.each(function() { var $element = $(this), total = $(options.slides).length; //... $(options.wrapper, $element).width($(options.slides).eq(0).width() * total); //... });

Здесь начальная ширина задана шириной каждого слайда. Нужно только задать общую ширину враппера.

Теперь внутренний контейнер достаточно широк. На чистом JS это делается примерно так же:

// Слайд-шоу на всю ширину Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); //... this.total = this.slides.length; this.setDimensions(); this.actions(); }, setDimensions: function() { var self = this; // Viewport"s width var winWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var wrapperWidth = winWidth * self.total; for(var i = 0; i < self.total; ++i) { var slide = self.slides[i]; slide.style.width = winWidth + "px"; } self.wrapper.style.width = wrapperWidth + "px"; }, //... }; // Слайд-шоу фиксированной ширины Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.slides = this.el.querySelectorAll(".slide"); //... this.total = this.slides.length; this.setDimensions(); this.actions(); }, setDimensions: function() { var self = this; var slideWidth = self.slides.offsetWidth; // Single slide"s width var wrapperWidth = slideWidth * self.total; self.wrapper.style.width = wrapperWidth + "px"; }, //... };

Эффекты исчезновения Эффекты исчезновения (fade) часто используются в слайд-шоу. Текущий слайд исчезает, и появляется следующий. У jQuery есть методы fadeIn() и fadeOut(), которые работают как со свойством opacity, так и с display, поэтому элемент удаляется из страницы по завершению анимации (display:none).

В чистом JS лучше всего работать со свойством opacity и использовать стек позиционирования CSS. Тогда изначально слайд будет видимым (opacity: 1), а другие - спрятаны (opacity:0).

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

Slider { width: 100%; overflow: hidden; position: relative; height: 400px; } .slider-wrapper { width: 100%; height: 100%; position: relative; } .slide { position: absolute; width: 100%; height: 100%; opacity: 0; } .slider-wrapper > .slide:first-child { opacity: 1; }

В чистом JS необходимо зарегистрировать переход CSS каждого слайда:

Slide { float: left; position: absolute; width: 100%; height: 100%; opacity: 0; transition: opacity 500ms linear; }

С jQuery для использования методов fadeIn() и fadeOut() надо менять opacity и display:

Slide { float: left; position: absolute; width: 100%; height: 100%; display: none; } .slider-wrapper > .slide:first-child { display: block; }

В jQuery код следующий:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", previous: ".slider-previous", next: ".slider-next", slides: ".slide", nav: ".slider-nav", speed: 500, easing: "linear" }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $currentSlide. animate({ opacity: 1 }, options.speed, options.easing). siblings(options.slides). css("opacity", 0); }; //... }; })(jQuery);

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

В JavaScript это будет:

Slideshow.prototype = { //... _slideTo: function(slide) { var currentSlide = this.slides; currentSlide.style.opacity = 1; for(var i = 0; i < this.slides.length; i++) { var slide = this.slides[i]; if(slide !== currentSlide) { slide.style.opacity = 0; } } }, //... };

Медийные элементы: видео Мы можем включать видео в слайд-шоу. Вот пример слайд-шоу с видео от Vimeo:

Видео включаются через iframe. Это такой же заменяемый inline-block, как и картинка. Заменяемый – потому, что содержимое взято из внешнего источника.

Чтобы создать полностраничное слайд-шоу, надо поменять стили следующим образом:

Html, body { margin: 0; padding: 0; height: 100%; min-height: 100%; /* Высота должна быть со всю страницу */ } .slider { width: 100%; overflow: hidden; height: 100%; min-height: 100%; /* Высота и ширина на полную */ position: absolute; /* Абсолютное позиционирование */ } .slider-wrapper { width: 100%; height: 100%; /* Высота и ширина на полную */ position: relative; } .slide { float: left; position: absolute; width: 100%; height: 100%; } .slide iframe { display: block; /* Блочный элемент */ position: absolute; /* Абсолютное позиционирование */ width: 100%; height: 100%; /* Высота и ширина на полную */ }

Автоматические слайд-шоу Автоматические слайд-шоу используют таймеры. При каждом обратном вызове функции по таймеру setInterval() курсор будет увеличиваться на 1 и таким образом будет выбираться следующий слайд.

Когда курсор достигнет максимального количества слайдов, его надо обнулить.

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

(function($) { $.fn.slideshow = function(options) { options = $.extend({ slides: ".slide", speed: 3000, easing: "linear" }, options); var timer = null; // Таймер var index = 0; // Курсор var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $currentSlide.stop(true, true). animate({ opacity: 1 }, options.speed, options.easing). siblings(options.slides). css("opacity", 0); }; var autoSlide = function(element) { // Инициализируем последовательность timer = setInterval(function() { index++; // Увеличим курсор на 1 if(index == $(options.slides, element).length) { index = 0; // Обнулим курсор } slideTo(index, element); }, options.speed); // Тот же интервал, что и в методе.animate() }; var startStop = function(element) { element.hover(function() { // Останавливаем анимацию clearInterval(timer); timer = null; }, function() { autoSlide(element); // Возобновляем анимацию }); }; return this.each(function() { var $element = $(this); autoSlide($element); startStop($element); }); }; })(jQuery);

Оба параметра метода.stop() установлены в true, т.к. нам не нужно создавать очередь анимации из нашей последовательности.

На чистом JS код становится проще. Регистрируем переход CSS для каждого слайда с определённой длительности:

Slide { transition: opacity 3s linear; /* 3 секунды = 3000 миллисекунд */ }

И код будет следующим:

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.slides = this.el.querySelectorAll(".slide"); this.index = 0; // Курсор this.timer = null; // Таймер this.action(); this.stopStart(); }, _slideTo: function(slide) { var currentSlide = this.slides; currentSlide.style.opacity = 1; for(var i = 0; i < this.slides.length; i++) { var slide = this.slides[i]; if(slide !== currentSlide) { slide.style.opacity = 0; } } }, action: function() { var self = this; // Initializes the sequence self.timer = setInterval(function() { self.index++; // Увеличим курсор на 1 if(self.index == self.slides.length) { self.index = 0; // Обнулим курсор } self._slideTo(self.index); }, 3000); // Тот же интервал, что и у перехода CSS }, stopStart: function() { var self = this; // Останавливаем анимацию self.el.addEventListener("mouseover", function() { clearInterval(self.timer); self.timer = null; }, false); // Возобновляем анимацию self.el.addEventListener("mouseout", function() { self.action(); }, false); } }; })();

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

Для этого мы обратимся к свойству keyCode объекта event. Оно возвращает код нажатой клавиши (список кодов).

Те события, что мы прикрепляли на кнопки "Предыдущий" и "Следующий", теперь можно прикрепить на клавиши "влево" и "вправо". jQuery:

$("body").on("keydown", function(e) { var code = e.keyCode; if(code == 39) { // Стрелка влево $next.trigger("click"); } if(code == 37) { // Стрелка вправо $previous.trigger("click"); } });

На чистом JS вместо простого метода.trigger() придётся пользоваться dispatchEvent():

Document.body.addEventListener("keydown", function(e) { var code = e.keyCode; var evt = new MouseEvent("click"); // нажатие мыши if(code == 39) { // Стрелка влево self.next.dispatchEvent(evt); } if(code == 37) { // Стрелка вправо self.previous.dispatchEvent(evt); } }, false);

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

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

В jQuery можно создать обратный вызов так:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ //... callback: function() {} }, options); var slideTo = function(slide, element) { var $currentSlide = $(options.slides, element).eq(slide); $currentSlide. animate({ opacity: 1 }, options.speed, options.easing, // Обратный вызов для текущего слайда options.callback($currentSlide)). siblings(options.slides). css("opacity", 0); }; //... }; })(jQuery);

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

$(function() { $("#main-slider").slideshow({ callback: function(slide) { var $wrapper = slide.parent(); // Показывает текущую подпись и прячет остальные $wrapper.find(".slide-caption").hide(); slide.find(".slide-caption").show("slow"); } }); });

На чистом JS:

(function() { function Slideshow(element, callback) { this.callback = callback || function() {}; // Our callback this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { //... this.slides = this.el.querySelectorAll(".slide"); //... //... }, _slideTo: function(slide) { var self = this; var currentSlide = self.slides; currentSlide.style.opacity = 1; for(var i = 0; i < self.slides.length; i++) { var slide = self.slides[i]; if(slide !== currentSlide) { slide.style.opacity = 0; } } setTimeout(self.callback(currentSlide), 500); // Вызывает функцию по окончанию перехода } }; // })();

Функция обратного вызова определена как второй параметр конструктора. Использовать её можно так:

Document.addEventListener("DOMContentLoaded", function() { var slider = new Slideshow("#main-slider", function(slide) { var wrapper = slide.parentNode; // Показывает текущую подпись и прячет остальные var allSlides = wrapper.querySelectorAll(".slide"); var caption = slide.querySelector(".slide-caption"); caption.classList.add("visible"); for(var i = 0; i < allSlides.length; ++i) { var sld = allSlides[i]; var cpt = sld.querySelector(".slide-caption"); if(sld !== slide) { cpt.classList.remove("visible"); } } }); });

Внешние API Пока наш сценарий работы прост: все слайды уже есть в документе. Если нам надо вставлять в него данные снаружи (YouTube, Vimeo, Flickr), нам нужно на лету заполнять слайды по мере получения внешнего контента.

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

Предыдущий Следующий

Это может быть gif или анимация на чистом CSS:

#spinner { border-radius: 50%; border: 2px solid #000; height: 80px; width: 80px; position: absolute; top: 50%; left: 50%; margin: -40px 0 0 -40px; } #spinner:after { content: ""; position: absolute; background-color: #000; top:2px; left: 48%; height: 38px; width: 2px; border-radius: 5px; -webkit-transform-origin: 50% 97%; transform-origin: 50% 97%; -webkit-animation: angular 1s linear infinite; animation: angular 1s linear infinite; } @-webkit-keyframes angular { 0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(360deg);} } @keyframes angular { 0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);} } #spinner:before { content: ""; position: absolute; background-color: #000; top:6px; left: 48%; height: 35px; width: 2px; border-radius: 5px; -webkit-transform-origin: 50% 94%; transform-origin: 50% 94%; -webkit-animation: ptangular 6s linear infinite; animation: ptangular 6s linear infinite; } @-webkit-keyframes ptangular { 0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(360deg);} } @keyframes ptangular { 0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);} }

Шаги будут такие:
- запросить данные извне
- спрятать загрузчик
- разобрать данные
- построить HTML
- вывести слайд-шоу
- обрабатывать слайд-шоу

Допустим, мы выбираем самые свежие видео пользователя с YouTube. jQuery:

(function($) { $.fn.slideshow = function(options) { options = $.extend({ wrapper: ".slider-wrapper", //... loader: "#spinner", //... limit: 5, username: "learncodeacademy" }, options); //... var getVideos = function() { // Получить видео с YouTube var ytURL = "https://gdata.youtube.com/feeds/api/videos?alt=json&author=" + options.username + "&max-results=" + options.limit; $.getJSON(ytURL, function(videos) { // Получаем видео как объект JSON $(options.loader).hide(); // Прячем загрузчик var entries = videos.feed.entry; var html = ""; for(var i = 0; i < entries.length; ++i) { // Разбираем данные и строим строку HTML var entry = entries[i]; var idURL = entry.id.$t; var idVideo = idURL.replace("http://gdata.youtube.com/feeds/api/videos/", ""); var ytEmbedURL = "https://www.youtube.com/embed/" + idVideo + "?rel=0&showinfo=0&controls=0"; html += ""; html += ""; html += ""; } $(options.wrapper).html(html); // Выведем слайд-шоу }); }; return this.each(function() { //... getVideos(); // Обрабатываем слайд-шоу }); }; })(jQuery);

На чистом JavaScript есть лишний шаг – создание метода получения JSON:

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.loader = this.el.querySelector("#spinner"); //... this.limit = 5; this.username = "learncodeacademy"; }, _getJSON: function(url, callback) { callback = callback || function() {}; var request = new XMLHttpRequest(); request.open("GET", url, true); request.send(null); request.onreadystatechange = function() { if (request.status == 200 && request.readyState == 4) { var data = JSON.parse(request.responseText); // JSON object callback(data); } else { console.log(request.status); } }; }, //... }; })();

Затем процедуры получаются схожие:

(function() { function Slideshow(element) { this.el = document.querySelector(element); this.init(); } Slideshow.prototype = { init: function() { this.wrapper = this.el.querySelector(".slider-wrapper"); this.loader = this.el.querySelector("#spinner"); //... this.limit = 5; this.username = "learncodeacademy"; this.actions(); }, _getJSON: function(url, callback) { callback = callback || function() {}; var request = new XMLHttpRequest(); request.open("GET", url, true); request.send(null); request.onreadystatechange = function() { if (request.status == 200 && request.readyState == 4) { var data = JSON.parse(request.responseText); // JSON object callback(data); } else { console.log(request.status); } }; }, //... getVideos: function() { var self = this; // Получить видео YouTube var ytURL = "https://gdata.youtube.com/feeds/api/videos?alt=json&author=" + self.username + "&max-results=" + self.limit; self._getJSON(ytURL, function(videos) { // Получаем видео как объект JSON var entries = videos.feed.entry; var html = ""; self.loader.style.display = "none"; // Прячем загрузчик for(var i = 0; i < entries.length; ++i) { // Разбираем данные и строим строку HTML var entry = entries[i]; var idURL = entry.id.$t; var idVideo = idURL.replace("http://gdata.youtube.com/feeds/api/videos/", ""); var ytEmbedURL = "https://www.youtube.com/embed/" + idVideo + "?rel=0&showinfo=0&controls=0"; html += ""; html += ""; html += ""; } self.wrapper.innerHTML = html; // Выводим слайд-шоу }); }, actions: function() { var self = this; self.getVideos(); // Обрабатываем слайд-шоу } }; })(); Добавить метки

1. Превосходное jQuery слайд-шоу

Большое эффектное слайд-шоу с использованием jQuery технологий.

2. jQuery плагин «Scale Carousel»

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

3. jQuery плагин «slideJS»

Слайдер изображений с текстовым описанием.

4. Плагин «JSliderNews» 5. CSS3 jQuery слайдер

При наведении курсора на стрелки навигации появляется круглая миниатюра следующего слайда.

6. Симпатичный jQuery слайдер «Presentation Cycle»

jQuery слайдер с индикатором загрузки изображений. Предусмотрена автоматическая смена слайдов.

7. jQuery плагин «Parallax Slider»

Слайдер с объемным фоновым эффектом. Изюминка этого слайдера в движение фона, который состоит из нескольких слоев, каждый из которых прокручивается с различной скоростью. В итоге получается имитация объемного эффекта. Выглядит очень красиво, вы можете сами в этом убедиться. Более плавно эффект отображается в таких браузерах как: Opera, Google Chrome, IE.

8. Свежий, легкий jQuery слайдер «bxSlider 3.0»

На демонстрационной странице в разделе «examples» вы сможете найти ссылки на все возможные варианты использования этого плагина.

9. jQuery слайдер изображений, плагин «slideJS»

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

10. jQuery плагин слайд-шоу «Easy Slides» v1.1

Простой в использовании JQuery плагин для создания слайд-шоу.

11. Плагин «jQuery Slidy»

Легкий jQuery плагин в различном исполнении. Предусмотрена автоматическая смена слайдов.

12. jQuery CSS галерея с автоматической сменой слайдов

Если посетитель в течении определенного времени не нажмет на стрелки «Вперед» или «Назад», то галерея начнет прокручиваться автоматически.

13. jQuery слайдер «Nivo Slider»

Очень профессиональный качественный легкий плагин с валидным кодом. Предусмотрено много различных эффектов смены слайдов.

14. jQuery слайдер «MobilySlider»

Свежий слайдер. jQuery слайдер с различными эффектами смены изображений.

15. jQuery Плагин «Slider²»

Легкий слайдер с автоматической сменой слайдов.

16. Свежий javascript слайдер

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

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

jQuery CSS слайдер изображений с использованием плагина NivoSlider .

19. jQuery слайдер«jShowOff»

Плагин для ротации содержимого. Три варианта использования: без навигации (с автоматической сменой в формате слайд-шоу), с навигацией в виде кнопок, с навигацией в виде миниатюр изображений.

20. Плагин «Shutter Effect Portfolio»

Свежий jQuery плагин для оформления портфолио фотографа. В галерее реализован интересный эффект смены изображений. Фотографии сменяют друг друга с эффектом похожим на работу затвора объектива.

21. Легкий javascript CSS слайдер «TinySlider 2»

Реализация слайдера изображений с использованием javascript и CSS.

22. Обалденный слайдер «Tinycircleslider»

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

23. Слайдер изображений на jQuery

Легкий слайдер «Slider Kit». Слайдер представлен в различном исполнении: вертикальный и горизонтальный. Также реализованы различные виды навигации между изображениями: с помощью кнопок «Вперед» и «Назад», с помощью колеса мыши, с помощью клика мыши по слайду.

24. Галерея с миниатюрами «Slider Kit»

Галерея «Slider Kit». Прокрутка миниатюр осуществляется как в вертикальном так и горизонтальном направлении. Переход между изображениями осуществляется с помощью: колеса мыши, щелчка мыши или наведения курсора на миниатюру.

25. jQuery слайдер содержимого «Slider Kit»

Вертикальный и горизонтальный слайдер контента на jQuery.

26. jQuery слайд-шоу «Slider Kit»

Слайд-шоу с автоматической сменой слайдов.

27. Легкий профессиональный javascript CSS3 слайдер

Аккуратный слайдер на jQuery и CSS3, созданный в 2011 году.

jQuery слайд-шоу с миниатюрами.

29. Простое jQuery слайд-шоу

Слайд-шоу с кнопками навигации.

30. Потрясное слайд-шоу jQuery «Skitter»

jQuery плагин «Skitter» для создания потрясающего слайд-шоу. Плагин поддерживает 22 (!) вида различных анимационных эффектов при смене изображений. Может работать с двумя вариантами навигации по слайдам: с помощью номеров слайдов и с помощью миниатюр. Обязательно посмотрите демонстрацию, очень качественная находка. Используемые технологии: CSS, HTML, jQuery, PHP.

31. Слайд-шоу «Awkward»

Функциональное слайд-шоу. В виде слайдов могут выступать: простые изображения, изображения с подписями, изображения с всплывающими подсказками, видео-ролики. Для навигации можно использовать стрелки, ссылки на номера слайдов и клавиши вправо/влево на клавиатуре. Слайд-шоу выполнено в нескольких вариантах: с миниатюрами и без них. Для просмотра всех вариантов пройдитесь по ссылкам Demo #1 - Demo #6 расположенным сверху на демонстрационной странице.

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

Анимированный jQuery слайдер. Фоновые изображения автоматически масштабируются при изменении размеров окна браузера. Для каждого изображения выплывает блок с описанием.

34. «Flux Slider» слайдер на jQuery и CSS3

Новый jQuery слайдер. Несколько классных анимированных эффектов при смене слайдов.

35. jQuery плагин «jSwitch»

Анимированная jQuery галерея.

Легкое слайд-шоу на jQuery c автоматической сменой слайдов.

37. Новая версия плагина «SlideDeck 1.2.2»

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

38. jQuery слайдер «Sudo Slider»

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

39. jQuery CSS3 слайд-шоу

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

40. jQuery cлайдер «Flux Slider»

Слайдер с множеством эффектов смены изображений.

41. Простой jQuery слайдер

Стильный слайдер изображений на jQuery.

Всем привет. С вами Corvax. Сегодня я вам покажу как легко можно создать совой слайдер галереи фотографий на чистом javascript. Приступим.

В начале нам нужно будет создать структуру проекта. Вот пример:

Верстка HTML

В файле index.html нужно сверстать следующую структуру.

Стили CSS #gallery{ width: 400px; text-align: center; margin: 0 auto; } .photo{ position: relative; height: 300px; } .photo img{ width: 100%; position: absolute; opacity: 0; left: 0; transition: opacity 1s; } .photo img.shown{ opacity: 1; } .tabs{ text-align: center; padding-top: 20px; }

Основной момент на который тут стоит обратить внимание это то что мы по умолчанию делаем все картинки прозрачными (opacity: 0). И на класс shown добовляем свойство opacity: 1.

Добавляем JS var btn_prev = document.querySelector(".tabs .prev"), btn_next = document.querySelector(".tabs .next"); var images = document.querySelectorAll(".photo img"); var i = 0; btn_prev.onclick = function(){ images[i].className = ""; i = i - 1; if(i = images.length){ i = 0; } images[i].className = "shown"; };

Тут находится самая интересная часть. В начале мы инициализируем две кнопки на которые будем вешать события клика и набор фотографий (btn_prev, btn_next, images). После инициализации мы накидываем событие onclick на кнопки которые будут листать наш слайдер.

images[i].className = «»; тут мы убираем по клику класс shown со всех картинок.

i ++ (—) здесь мы будем при каждом клике менять индификатор слайда

if(i > = images.length){ i = 0; } (условие по клику на кнопку «вперед») это условие нам нужно что бы проверить когда будет выбран последний слайд. Если мы выбрали слайд который больше последнего то мы будем индификатору присваивать 0 (что автоматически поставит нас в начало набора).

if(i < 0){ i = images.length — 1; } (условие по клику на кнопку «назад») здесь если индификатор картники меньше 0 то индификатор будет равен последнему слайду -1 (т.к. массив у нас начинается с 0)

images[i].className = «shown»; тут мы добавляем класс shown на текущий активный слайд.

Заключение

Сегодня мы сделали собственный слайдер на нативном JS. вы можете получить исходных код. С вами был Corvax. Удачи в разработке!