Створення jQuery плагін слайд шоу з нуля

1

Від автора: Багато речей щодо того, як ми підходимо до розробки фронт енду, значно змінилися за останні пару років. У всіх нас є улюблені плагіни, які ми використовуємо при необхідності, багато з них були створені в часи фіксованих сіток, але, можливо, вони вже не є найкращими інструментами для роботи. Що робити нам, коли це відбувається? Шукати нові інструменти або створювати свої власні?

Створення jQuery плагін слайд шоу з нуля

Передмова

Що стосується змін у нашій роботі, самим очевидним є підхід до кожного проекту як «гумовому», чуйному, створеного з нуля. На щастя, у нас є відмінні інструменти, що входять у саму специфікацію CSS, такі як відсотки і медіа-запити, щоб допомогти нам. Але багато хто з наших улюблених плагінів для таких речей як слайд шоу, каруселі, модальні вікна, мають один фатальний недолік, коли справа доходить до чуйною розмітки – вбудовані стилі, додаються JavaScript’ом і безліч їх. Коли ми намагаємося використовувати ці плагіни в «новому поколінні» чуйних сайтів, це закінчується тим, що ми постійно боремося з цими стилями з хакерськими переопределениями або чимось гіршим, з’являється ще більше JavaScript коду, щоб контролювати поведінку і витіснити старий код.

Що ж нам потрібно контролювати за допомогою JavaScript?

Для мене хороший фронт енд плагін для «чуйною ери», повинен виробляти абсолютний мінімум вбудованих стилів, необхідних для роботи, і нічого більше. Наприклад, якщо нам потрібен простий плагін слайд-шоу, в якому набір картинок змінюється з ефектом знебарвлення, що нам дійсно потрібно контролювати за допомогою JavaScript? Якщо ми на секунду задумаємося над цим, то можливо це будуть властивості opacity і z-index, і нічого більше. Коли ви бачите як слайд шоу генерує такі речі, як позиціонування, ширину і висоту і обтікання, настає час визнати, що плагін можливо співслужив свою службу в часи фіксованих сіток, але настав час рухатися далі.

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

Я задумався над тим, наскільки складно буде створити легкий плагін слайд шоу з чистого аркуша

Як виявилося, це не так складно, як здається, і можливо навіть швидше і (куди більш захоплююче), ніж намагатися переробляти вже існуючий плагін, так щоб він став вашим цілям. З тих пір я написав безліч плагінів для фронт енду і працюю над багатьма наступними. Бути відповідальним за кожну строчку коду у вашому проекті – це чудова річ, і я подумав, що варто написати цю статтю, щоб надихнути більше розробників на написання власних інструментів і дати їм зрозуміти, що розробка плагінів – це не темне містичне мистецтво, доступне одиницям.

У цій статті я покроково проведу вас через цей процес. Ми будемо вдаватися в деталі в міру прогресу, і хоча я зроблю все можливе, але вам ця стаття буде корисна, якщо ви впевнено працюєте з jQuery і її методами, а також має досвід написання JavaScript коду з нуля, використовуючи змінні і функції.

Бути відповідальним за кожну строчку коду у вашому проекті – це чудова річ

Фаза 1: Концептуалізація

Створення jQuery плагін слайд шоу з нуля

Перш ніж почати. Мені здається корисною візуалізація того, як плагін буде працювати, і який функціонал знадобиться. Чому б не почати з того, щоб написати список або не зробити швидкий начерк?

Функціонал

Плагін буде програмно знебарвлюватися крізь набір абсолютно позиціонованих елементів допомогою анимирования їх непрозорість.

Слайди можуть бути картинками або будь-якими іншими елементами, укладеними div.

Щоб переконатися в тому, що ми можемо перейти від одного слайда до іншого (вони необов’язково можуть знаходитися на одному рівні по відношенню до батьківського елементу) нам також потрібно змінювати значення z-index в них.

Плагін повинен використовувати властивість CSS3 transition, коли можливо або ж jQuery .animate().

Властивості

Автоматично переміщати слайди по порядку, зупиняючись на період часу, визначений користувачем.

Переміщати слайди по кліку, використовуючи елементи керування вперед/назад.

Показувати певний слайд безпосередньо за допомогою списку кнопок з класом «pager».

Дозволяти користувачеві конфігурувати інтервал таймера, а також інтервал знебарвлення з моменту початку показу слайдів.

Фаза 2: Створення (Швидке і з похибками)

Створення jQuery плагін слайд шоу з нуля

Як згадувалося раніше, найкращою практикою для створення чуйних плагінів – це залишити якомога більше стилізації для таблиці стилів, і використовувати вбудовані стилі, додаються JavaScript’му тільки там, де це необхідно. Маючи зважаючи на вищесказане, давайте почнемо з написання HTML і CSS.

Створення jQuery плагін слайд шоу з нуля
Створення jQuery плагін слайд шоу з нуля

Я уявляю, що на самому базовому рівні, розмітка нашого слайд шоу буде виглядати якось так. Як згадувалося раніше, самі слайди не повинні бути обмежені тільки зображеннями, тому я додав кілька div тегів. Таким чином, наш плагін повинен ідентифікувати їх як слайди завдяки класу «slide», а не по тегах або позиції в DOM.

Наш контейнер в ідеалі повинен містити й клас і ідентифікатор. Ми будемо використовувати клас для визначення стилів слайд шоу, що дозволить нам мати кілька слайд шоу на одній сторінці, і ми будемо використовувати ID, щоб звертатися до кожного слайд шоу з допомогою jQuery унікально.

Давайте перейдемо до CSS. Для мене, це те місце, де наш код може бути дійсно елегантним, знову оголосивши тільки те, що необхідно, і використовуючи якомога менше значень. Наступні стилі припускають, що ми використовуємо глобальний скидання стилів (такий як чудовий CSS Reset) на самому початку таблиці стилів.

.fader{
position: relative;
padding-top: 60%;
overflow: hidden;
}
.fader .slide{
position: absolute;
width: 100%;
height: 100%;
top: 0;
z-index: 1;
opacity: 0;
}
.fader img.slide{
height: auto;
}

Замість того, щоб задавати висоту нашому контейнера, я волів змінити значення властивості padding-top. Цей прийом дозволяє масштабувати висоту елемента на основі його ширини, а не на основі висоти батьківського контейнера. Для слайд шоу з фіксованим співвідношенням ширини до висоти, це буде невід’ємною частиною чуйного поведінки. Я вибрав відношення 5 : 3 або, іншими словами, висота складає 60% ширини.

Ставлячи всім нашим слайдів z-index рівний 1, ми стискаємо природний порядок слайдів в рамках однакового значення z-index, будучи впевненими, що вони не будуть перешкоджати 2м верхнім сменяющимся слайдів, які мають z-index 2 і 3 (дивіться малюнок). Задаючи всіх слайдів непрозорість рівну 0, ми будемо контролювати те, який слайд з’явиться першим, коли нам потрібно і уникнемо так званої «спалахи нестилизованного контенту».

Останній стиль просто перепризначає 100% висоту значенням «height: auto» якщо елемент слайда є зображенням. Це засвідчує, що якщо зображення має відношення ширини до висоти, відмінне від 5:3, то воно не буде спотворюватися з-за висоти в 100%.

Тепер коли HTML і CSS в порядку, давайте перейдемо до цікавим речам – jQuery!

Що таке плагін jQuery крім того, що він є набором змінних і функцій? Це те, з чого мені подобається починати написання плагіна.

Що таке плагін jQuery крім того, що він є набором змінних і функцій?

Я збираюся скласти ще один список, в цей раз, що складається з даних, які необхідно зберігати, для того, щоб плагін працював, без певного порядку. Це будуть наші змінні.

Контейнер

Селектор класу слайда

Тривалість показу слайдів

Тривалість знебарвлення

Кількість слайдів

Порядковий номер поточного «активного» слайда

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

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

Контейнер — об’єкт jQuery

Селектор класу слайда — рядок

Тривалість показу слайдів – число (в мілісекундах)

Тривалість знебарвлення – число (в мілісекундах)

Кількість слайдів — число

Порядковий номер поточного «активного» слайда — число

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

Тепер час оголосити нашу найголовнішу функцію. Я вирішив назвати її easyFader, таким же буде і назва нашого плагіна.

function easyFader(){
}

Ми будемо створювати слайд шоу на сторінці допомогою виклику цієї функції, тому можливо нам знадобиться передати кілька аргументів цієї функції, для того, щоб наш плагін мав усі необхідні дані для початку роботи, і користувач мав можливість конфігурувати кожен примірник плагіна. Зі списку наведеного вище нам необхідно передати наступні дані:jQuery об’єкт контейнера, тривалість показу слайдів і тривалість знебарвлення. Все інше буде програмно розраховано пізніше. Ми можемо дати користувачеві можливість вибрати також селектор слайда, але поки що ми поставимо його в коді.

Ось як виглядає оголошена функція разом з заданими «аргументами»:

function easyFader($container, slideDur, fadeDur){
//Весь наш код буде тут.
}

Запам’ятайте: символ $ допомагає нам пам’ятати про те, що ця змінна є об’єктом jQuery.

Таким чином, коли ми викликаємо функцію для ініціалізації слайд шоу, вона буде виглядати так:

easyFader($(‘#Fader’),7000,800);

Це викличе плагін на елементі з ідентифікатором Fader, з тривалістю показу слайдів рівною 7 секунд, і періодом знебарвлення в 800 мілісекунд.

Можливо, ви помітили, що синтаксис виглядає як звичайна функція JavaScript, а не плагін jQuery, і ви будете абсолютно праві. Я думаю, що під час першого «швидкого» прототипування, найкращим шляхом є дотримуватися того, з чим ми найкращим чином знайомі, щоб зберегти час і уникнути непорозумінь. Ми доберемося до модних прийомів плагіна пізніше.

Я думаю, що під час першого «швидкого» прототипування, найкращим шляхом є дотримуватися того, з чим ми найкращим чином знайомі, щоб зберегти час і уникнути непорозумінь.

Першим кроком у наступному коді є створення порожнього об’єкта під назвою faderConfig і додавання його як властивості до сирого об’єкту DOM нашого контейнера. Щоб мати доступ до цього об’єкта jQuery ми просто розміщуємо [0] відразу після об’єкта jQuery, що рівнозначно window.getElementByID(‘Fader’) на чистому JavaScript. Саме там ми будемо зберігати всі чотири загальнодоступні налаштування конфігурації, і прив’язуючи його до DOM, наші дані не будуть замкнуті усередині нашої функції, і можуть бути доступні редактируемы ззовні в будь-який час, за межами функції слайд шоу.

Ця маленька хитрість дозволить нам мати кілька примірників плагіна на одній сторінці, без того, щоб вдаватися в більш складні об’єктно-орієнтовані структури, що включають класи, інстанції та методи, що лежить за межами цієї статті. Створюючи наш плагін як набір функцій, а не як об’єкт з методами, процес буде трохи легше для розуміння тим, хто пише свій перший плагін.

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

Ініціалізація

function easyFader($container, slideDur, fadeDur){
// Додаємо порожній конфігураційний об’єкт
// DOM об’єкту контейнера
$container[0].faderConfig = {};
// Кешуємо об’єкт як локальну змінну
var config = $container[0].faderConfig;
// Додаємо загальнодоступні властивості об’єкту
config = {
slideDur : slideDur,
fadeDur : fadeDur
}
// Оголошуємо приватні змінні. Вони будуть використовуватися для зберігання даних,
// які не визначаються користувачем.
var slideSelector = ‘.slide’, // selector for target elements
slideTimer, // will contain our setTimeout function
totalSlides, // total number of slides
activeSlide, // index of active slide
newSlide, // index of upcoming slide
$slides = $container.find(slideSelector);
// jQuery об’єкт, що містить всі слайди
// Find the total number of slides
totalSlides = $slides.length;

За замовчуванням, останній слайд DOM буде мати найвище значення z-index і таким чином буде показуватися першим, навіть якщо всі наші слайди придбають opacity:1. Проте, ми хочемо, щоб перший слайд показувався першим:

// Показати перший слайд використовуючи метод jQuery eq()
$slides.eq(0).css(‘непрозорість’,1);
// Тепер наш перший слайд активний
// давайте задамо змінної activeSlide значення 0
// (Запам’ятайте: в JavaScript, рахунок починається з 0, а не 1)
activeSlide = 0;
// Запускаємо таймер
slideTimer = setTimeout(function(){
changeSlides(‘next’);
},config.slideDur);

Так як ви бачите, після таймауту рівного налаштуванні slideDur, ми збираємося викликати нову функцію, названу changeSlides(). Ми передаємо їй єдиний аргумент зі значенням next, означає, що ми переходимо до нового слайду DOM. Наш аргумент changeSlides повинен приймати три різних значення: next, prev а також порядковий номер слайда на випадок, якщо ми захочемо перейти до певного слайда (поза порядку). Давайте перейдемо до написання цієї функції.

Зміна слайдів

function changeSlides(target){
// Створюємо умовний фреймворк для обробки
// трьох можливих варіантів
if(target == ‘next’){
// Націлюємося на наступний слайд
newSlide = activeSlide + 1;
// Перевіряємо не дійшли ми до кінця набору, і якщо так,
// то повертаємося на початок циклу
if(newSlide > totalSlides — 1){
newSlide = 0;
}
} else if(target == ‘prev’){
// Націлюємося на попередній слайд
newSlide = activeSlide — 1;
// Перевіряємо не дійшли ми до початок набору, і якщо так,
// то повертаємося кінець циклу
if(newSlide < 0){
newSlide = totalSlides — 1;
}
} else {
// Якщо не наступний і не попередній, націлюємося на певне число,
// таким чином метою є змінна newSlide
newSlide = target;
};
animateSlides(activeSlide, newSlide);
};

Тепер ми викликали третю функцію під назвою animateSlides(), яку ми будемо використовувати для того, щоб керувати анімацією знебарвлення. Функція animateSlides буде приймати два аргументи – порядковий номер поточного активного слайда, а також порядковий номер нового майбутнього слайда. Ці номери належать до позиції слайда в DOM щодо своїх побратимів і не повинні бути прийняті за z-index, який визначає вертикальний порядок.

Запам’ятайте: Мені подобається обертати код в його власну функцію тоді, коли мені здається, що його можна відокремити як модуль, який можна використовувати безліч разів або викликати в багатьох місцях. Розбивання коду на модульні функції зробить його легше для читання і підтримки. Так як ці другорядні функції вкладено в нашу батьківську функцію easyFader(), вони будуть мати доступ до наших налаштувань конфігурації, а також приватним змінним.

Анімація знебарвлення

function animateSlides(activeNdx, newNdx){
// Задаємо z-index 3 активного слайда
$slides.eq(activeNdx).css(‘z-index’, 3);
// Попереднього слайда задаємо z-index 2 а
// opacity рівне 1
$slides.eq(newNdx).css({
‘z-index: 2,
‘непрозорість’: 1
});
// Давайте буде дотримуватися методу jQuery .animate() поки
// і обесцвечиваем поточний слайд, щоб показати новий слайд під ним
$slides.eq(activeNdx).animate({‘непрозорість’: 0}, config.fadeDur,
function(){
// Видаляємо у елемента всі вбудовані стилі
$slides.eq(active).removeAttr(‘style’);
// Новий слайд стає активним
activeSlide = newNdx;
// Запускаємо таймер
waitForNext();
});
};

Зверніть увагу на те, що анімація визначає свою тривалість згідно налаштування конфігурації fadeDur. Останній шматочок головоломки – це функція waitForNext(). Якщо ви пам’ятаєте, ми оголосили приватну змінну» slideTimer» в самому початку. Тепер цієї змінної ми задамо функцію setTimeout() для того, щоб вона автоматично викликала наступний слайд по закінченню 7 секунд.

Таймер

function waitForNext(){
slideTimer = setTimeout(function(){
changeSlides(‘next’);
},config.slideDur);
};

Вітаю, якщо ви дочитали до цих пір ми тільки що створили прототип нашого першого плагіна! Ось весь код без коментарів з кількома незначними оптимизациями щодо порядку оголошення змінних.

Повне зібрання коду

function easyFader($container, slideDur, fadeDur){
$container[0].faderConfig = {};
var slideSelector = ‘.slide’,
slideTimer,
activeSlide,
newSlide,
$slides = $container.find(slideSelector),
totalSlides = $slides.length,
config = $container[0].faderConfig;
config = {
slideDur : slideDur,
fadeDur : fadeDur
};
$slides.eq(0).css(‘непрозорість’, 1);
activeSlide = 0;
slideTimer = setTimeout(function(){
changeSlides(‘next’);
},config.slideDur);
function changeSlides(target){
if(target == ‘next’){
newSlide = activeSlide + 1;
if(newSlide > totalSlides — 1){
newSlide = 0;
}
} else if(target == ‘prev’){
newSlide = activeSlide — 1;
if(newSlide < 0){
newSlide = totalSlides — 1;
};
} else {
newSlide = target;
};
animateSlides(activeSlide, newSlide);
};
function animateSlides(activeNdx, newNdx){
$slides.eq(activeNdx).css(‘z-index’, 3);
$slides.eq(newNdx).css({
‘z-index: 2,
‘непрозорість’: 1
});
$slides.eq(activeNdx).animate({‘непрозорість’: 0}, config.fadeDur, function(){
$slides.eq(activeNdx).removeAttr(‘style’);
activeSlide = newNdx;
waitForNext();
});
};
function waitForNext(){
slideTimer = setTimeout(function(){
changeSlides(‘next’);
},config.slideDur);
};
};

Досить легкий, не чи правда? Якщо ви дивуєтесь чому він настільки малий у порівнянні з більшістю плагінів для слайд шоу, які важать 30+Kb, то значить ми рухаємося у вірному напрямку.

Подивитися робочий прототип на Codepen

Фаза 3: Оптимізація, покращення та розширення

Перший крок в оптимізації – це визначити, які ділянки код повторюються без потреби. Так як наш плагін занадто малий на даному етапі, їх буде небагато, але один я вже бачу. Функція setTimeout(), яка викликається при ініціалізації містить той же код, що і функція waitForNext(). Так що давайте буде викликати цю функцію при ініціалізації. Крім того, все виглядає досить добре на даний момент, і ми мінімізуємо код надалі.

Давайте перейдемо до поліпшень. Справжні поліпшення і розвиток відбуваються зазвичай по закінченню тижнів і місяців, коли ми спробуємо плагін в різних середовищах, ідентифікуємо баги, додамо функціонал і перепишемо ділянки коду. Однак, для цілей цієї статті, поліпшення буде складатися в додаванні деякого функціоналу, якого ми не включили в початковий прототип. Це буде:

Кнопки вперед/назад і управління пагінація

Заміна методу jQuery .animate() на переходи CSS3, де можливо

Кнопки і елементи управління

Ми можемо або автоматично генерувати кнопки та елементи управління з допомогою jQuery, або ж включити їх у верстку, коли ми пишемо HTML. Я куди більше віддаю перевагу другий варіант, так як я вважаю, що рішення щодо розмітки, такі як стилізації, повинні бути на розсуд користувача, а не продиктовані плагіном.

рішення щодо розмітки, такі як стилізації, повинні бути на розсуд користувача, а не продиктовані плагіном.

Однак, що стосується списку кнопок пагинации, краще згенерувати їх динамічно на основі кількості слайдів, що є дуже корисним для ситуацій, пов’язаних з CMS.

Для кнопок управління, достатньо буде чогось такого:

Створення jQuery плагін слайд шоу з нуля
Створення jQuery плагін слайд шоу з нуля

    Ми просто прив’яжемо обробники кличу до чого завгодно всередині контейнера, що має клас page. Я також створив порожній елемент ul з класом pager_list, який буде містити кнопки пагинации. Клас fader_controls там знаходиться тільки для стилізації. Знову настав час JavaScript.

    В першу чергу, давайте побудуємо список кнопок. Це відбудеться при ініціалізації і буде виглядати якось так:

    var $pagerList = $container.find(‘.pager_list’);
    for(var i = 0; i < totalSlides; i++){
    $pagerList
    .append(‘

  • ‘+i+’
  • ‘);
    };

    Ми також поставимо першого елемента li в списку клас active при ініціалізації, щоб ми стилізувати його таким чином, щоб користувач бачив, що перший слайд активний.

    $pagers.eq(0).addClass(‘active’);

    Тепер я збираюся створити наші обробники подій. Цей шматок коду прив’яже обробники подій до наших кнопками і елементів управління, і також буде викликатися при ініціалізації:

    $container.find(‘.page’).bind(‘click’,function(){
    var target = $(this).attr(‘data-target’);
    changeSlides(target);
    });

    Таким чином, завжди, коли натискання миші відбувається на будь-якому елементі з класом page, викликається функція changeSlides() з аргументом, який є значення атрибута data-target поточного елемента. Знову три можливих значення – next, prev або число.

    Однак, є одна невелика проблема з цією функцією, полягає в тому, що таймер слайда, продовжуватиме працювати у фоновому режимі під час того, як натискати кнопки. Це може призвести до того, що слайд шоу буде раптово змінювати слайди, коли ми цього не очікуємо чи не хочемо. Щоб уникнути цього, нам потрібно очистити цей таймер, коли натискається кнопка. Ось перероблена функція:

    $container.find(‘.page’).bind(‘click’,function(){
    var target = $(this).attr(‘data-target’);
    clearTimeout(slideTimer);
    changeSlides(target);
    });

    Аналогічно, ми хочемо переконатися в тому, що якщо у нас на даний момент змінюються слайд, то користувач не повинен мати можливість натискати на кнопки і перервати анімацію, викликаючи численні анімації одночасно. Щоб домогтися цього, ми створимо нову приватну змінну з ім’ям fading, яка матиме значення false за замовчуванням. Коли анімація починається, ця змінна буде приймати значення true і назад false, коли вона закінчується. Якщо надходить виклик функції animateSlides() під час анімації, ми його заблокуємо, повертаючи значення false, ось так:

    function animateSlides(activeNdx, newNdx){
    if(fading){
    return false;
    };
    fading = true;

    Це також буде хорошим часом для блокування будь-якого виклику, де користувач перемикає вже активний слайд:

    function animateSlides(activeNdx, newNdx){
    if(fading || activeNdx == newNdx){
    return false;
    };
    fading = true;

    Коли ми дійсно змінюємо слайди, ми також хочемо, щоб активний елемент управління змінювався візуально. Наступний код буде знаходитися всередині функції animateSlides():

    $pagers.removeClass(‘active’).eq(newSlide).addClass(‘active’);

    Переходи CSS3

    Переходи CSS3 працюють дуже схожим чином, як і метод jQuery .animate() – плавно анимируют будь числове властивість CSS3 від одного значення до іншого. Велика різниця складається в тому, щоб відображення переходів CSS3 проводиться браузером без допомоги JavaScript, і часто отримає прискорення GPU, таким чином значно зменшуючи навантаження на процесор і збільшуючи частоту кадрів. Це особливо корисно для портативних пристроїв, таких як планшети і телефони з дуже поганою підтримкою JavaScript. Тепер, коли практично всі браузери підтримують переходи CSS3, має сенс використовувати їх за замовчуванням як спосіб анімації, використовуючи jQuery .animate() тоді, коли нам потрібно підтримувати IE9 (тому що IE8 навіть не підтримує opacity, тому в цій статті ми про нього забудемо).

    Для нашого плагіна, у першу чергу, ми переконаємося, що переходи CSS3 доступні, а потім умовно виберемо наш метод анімації всередині функції animateSlides().

    Ось відмінний код я використовував для MixItUp, щоб протестувати підтримку переходів CSS3 і якщо необхідно додати префікси виробників. Ми могли б використовувати бібліотеку для визначення підтримки браузером як Modernizr, але мета цієї вправи в тому, щоб створити екстра легкий самостійний плагін, який не буде мати залежностей крім самої jQuery.

    function prefix(el) {
    var prefixes = [«Webkit», «Moz», «O», «ms»];
    for (var i = 0; i < prefixes.length; i++){
    if (prefixes + «Transition» in el.style){
    return ‘-‘+prefixes.toLowerCase()+’-‘;
    };
    };
    return «transition» in el.style ? «» : false;
    };

    Ми просто передамо будь сирої елемент DOM йому, і він або поверне необхідний префікс для браузера або значення false, якщо підтримки немає. Якщо підтримка не вимагає префікса (що незабаром стане нормою), вона поверне пустий рядок. Ми її викличемо наступним чином:

    var prefix = prefix($container[0]);

    Якщо змінна prefix має значення false, значить, підтримки немає. Інакше ми доповнюємо рядок, щоб вона додавав необхідний код CSS.

    Тепер, коли виявлення переходів CSS3 встановлено, знову звернемося до нашої функції animateSlides().

    function animateSlides(activeNdx, newNdx){
    if(fading || activeNdx == newNdx){
    return false;
    };
    fading = true;
    $pagers.removeClass(‘active’).eq(newSlide).addClass(‘active’);
    $slides.eq(activeNdx).css(‘z-index’, 3);
    $slides.eq(newNdx).css({
    ‘z-index: 2,
    ‘непрозорість’: 1
    });
    if(!prefix){ // Якщо переходи не підтримуються, використовувати jQuery
    $slides.eq(activeNdx).animate({‘непрозорість’: 0}, config.fadeDur,
    function(){
    $slides.eq(active).removeAttr(‘style’);
    activeSlide = newNdx;
    fading = false;
    waitForNext();
    });
    } else { // Інакше використовувати CSS3
    // Так як ми не можемо використовувати як власні назви,
    // нам потрібно створити об’єкт, який буде містити наші стилі,
    // і потім застосувати наші властивості до них за допомогою наступного синтаксису
    var styles = {};
    styles[prefix+’transition’] = ‘непрозорість ‘+config.fadeDur+’ms’;
    styles[‘непрозорість’] = 0;
    // тепер отримаємо дані з об’єкту за допомогою методу .css()
    $slides.eq(activeNdx).css(styles);
    // тепер почекаємо коли закінчиться анімація
    var fadeTimer = setTimeout(function(){
    $slides.eq(activeNdx).removeAttr(‘style’);
    activeSlide = newNdx;
    fading = false;
    waitForNext();
    },config.fadeDur);
    };
    };

    Ми також могли б просто оголосити перехід непрозорості безліч разів з усіма необхідними префіксами використовуючи метод .css(), але цей метод значно чистіше, так як він спрямований тільки на той браузер, який використовується. Ви могли помітити, що є простір для оптимізації тут, коли код виконується після того, як анімація закінчиться, повторюється для обох методів. Давайте винесемо його в окрему функцію і назвемо її cleanup(), яка буде знаходитися всередині animateSlides():

    function cleanUp(){
    $slides.eq(activeNdx).removeAttr(‘style’);
    activeSlide = newNdx;
    fading = false;
    waitForNext();
    };

    От і все! Ось версія № 2:

    Повна агрегована версія № 2 (Преміум)

    function easyFader($container, slideDur, fadeDur){
    $container[0].faderConfig = {};
    var slideSelector = ‘.slide’,
    fading = false,
    slideTimer,
    activeSlide,
    newSlide,
    $slides = $container.find(slideSelector),
    totalSlides = $slides.length,
    $pagerList = $container.find(‘.pager_list’);
    prefix = prefix($container[0]),
    config = $container[0].faderConfig;
    config = {
    slideDur : slideDur,
    fadeDur : fadeDur
    };
    for(var i = 0; i < totalSlides; i++){
    $pagerList
    .append(‘

  • ‘+i+’
  • ‘);
    };
    $container.find(‘.page’).bind(‘click’,function(){
    var target = $(this).attr(‘data-target’);
    clearTimeout(slideTimer);
    changeSlides(target);
    });
    var $pagers = $pagerList.find(‘.page’);
    $slides.eq(0).css(‘непрозорість’, 1);
    $pagers.eq(0).addClass(‘active’);
    activeSlide = 0;
    slideTimer = setTimeout(function(){
    changeSlides(‘next’);
    },config.slideDur);
    function changeSlides(target){
    if(target == ‘next’){
    newSlide = activeSlide + 1;
    if(newSlide > totalSlides — 1){
    newSlide = 0;
    }
    } else if(target == ‘prev’){
    newSlide = activeSlide — 1;
    if(newSlide < 0){
    newSlide = totalSlides — 1;
    };
    } else {
    newSlide = target;
    };
    animateSlides(activeSlide, newSlide);
    };
    function animateSlides(active, new){
    if(fading || activeNdx == newNdx){
    return false;
    };
    fading = true;
    $pagers.removeClass(‘active’).eq(newSlide).addClass(‘active’);
    $slides.eq(active).css(‘z-index’, 3);
    $slides.eq(new).css({
    ‘z-index: 2,
    ‘непрозорість’: 1
    });
    if(!prefix){
    $slides.eq(active).animate({‘непрозорість’: 0}, config.fadeDur,
    function(){
    cleanUp();
    });
    } else {
    var styles = {};
    styles[prefix+’transition’] = ‘непрозорість ‘+config.fadeDur+’ms’;
    styles[‘непрозорість’] = 0;
    $slides.eq(active).css(styles);
    var fadeTimer = setTimeout(function(){
    cleanUp();
    },config.fadeDur);
    };
    function cleanUp(){
    $slides.eq(active).removeAttr(‘style’);
    activeSlide = new;
    fading = false;
    waitForNext();
    };
    };
    function waitForNext(){
    slideTimer = setTimeout(function(){
    changeSlides(‘next’);
    },config.slideDur);
    };
    function prefix(el){
    var prefixes = [«Webkit», «Moz», «O», «ms»];
    for (var i = 0; i < prefixes.length; i++){
    if (prefixes + «Transition» in el.style){
    return ‘-‘+prefixes.toLowerCase()+’-‘;
    };
    };
    return «transition» in el.style ? «» : false;
    };
    };

    Фаза 4: Перетворення в даний плагін jQuery

    Останнім кроком буде перетворення цього:

    easyFader($(‘#Fader’),7000,800);

    У це:

    $(‘#Fader’).easyFader({
    slideDur: 7000,
    fadeDur: 800
    });

    Роблячи це, ми перетворюємо функцію метод jQuery, який ми можемо викликати на нашому об’єкті jQuery $(‘#Fader’). Щоб домогтися цього, нам потрібно инкапсулировать весь наш код на щось таке:

    (function($){
    var methods = {
    //Оголосимо метод init
    init: function(settings){
    // Завжди повертайте «this» для того, щоб jQuery методи могли слідувати один за іншим
    return this.each(function(){
    // Створюємо об’єкт конфігураційний
    // з передбаченими значеннями за промовчанням
    var config = {
    slideDur: 7000,
    fadeDur: 800
    };
    // Якщо користувач визначає конфігураційні установки,
    // поєднуємо їх в конфігураційний об’єкт,
    // щоб перезаписати значення за замовчуванням
    if(settings){
    $.extend(config, settings);
    };
    // Весь інший код буде тут
    };
    });
    }
    };
    // Оголошуємо плагін
    $.fn.easyFader = function(settings){
    // Викликаємо метод init при ініціалізації
    return methods.init.apply(this, arguments);
    };
    })(jQuery);

    За допомогою цього коду ми створюємо приватну функцію з залежністю JQuery, і в ній ми оголошуємо ім’я плагін jQuery «easyFader», і його доступні методи. Зараз нам потрібно тільки ініціалізації метод «init», але ця структура дозволить нам додати додаткові методи пізніше, якщо ми захочемо.

    Встановивши за замовчуванням значення для slideDur і fadeDur (7000 мс і 800 мс), ми гарантуємо, що користувач може запустити плагін прямо з коробки, без необхідності вказувати ці два значення. Якщо користувач вирішить вказати їх виразно, значення за замовчуванням будуть перезаписані тими значеннями, які визначить користувач.

    Запам’ятайте: в ідеальному варіанті, ми могли б конвертувати більшість наших функцій (наприклад, changeSlides () і animateSlides ()) в свої методи. У цій статті, однак, ми залишимо їх у вигляді функцій, щоб уникнути необхідності мати справу з більш передовими концепціями, як конструктора функцій і прототипів.

    Щоб дати можливість будь-якому JavaScript коду виконуватися як можна швидше, ми захочемо визначити наші функції, перш ніж ми їх викликаємо, що є протилежністю того, що ми робили досі. Таким чином, ви помітите, новий зворотний порядок виконання в остаточному коді.

    Не мудруючи лукаво, я уявляю jQuery EasyFader!

    (function($){
    function prefix(el){
    var prefixes = [«Webkit», «Moz», «O», «ms»];
    for (var i = 0; i < prefixes.length; i++){
    if (prefixes + «Transition» in el.style){
    return ‘-‘+prefixes.toLowerCase()+’-‘;
    };
    };
    return «transition» in el.style ? «» : false;
    };
    var methods = {
    init: function(settings){
    return this.each(function(){
    var config = {
    slideDur: 7000,
    fadeDur: 800
    };
    if(settings){
    $.extend(config, settings);
    };
    this.config = config;
    var $container = $(this),
    slideSelector = ‘.slide’,
    fading = false,
    slideTimer,
    activeSlide,
    newSlide,
    $slides = $container.find(slideSelector),
    totalSlides = $slides.length,
    $pagerList = $container.find(‘.pager_list’);
    prefix = prefix($container[0]);
    function waitForNext(){
    slideTimer = setTimeout(function(){
    changeSlides(‘next’);
    },config.slideDur);
    };
    function animateSlides(activeNdx, newNdx){
    function cleanUp(){
    $slides.eq(activeNdx).removeAttr(‘style’);
    activeSlide = newNdx;
    fading = false;
    waitForNext();
    };
    if(fading || activeNdx == newNdx){
    return false;
    };
    fading = true;
    $pagers.removeClass(‘active’).eq(newSlide).addClass(‘active’);
    $slides.eq(activeNdx).css(‘z-index’, 3);
    $slides.eq(newNdx).css({
    ‘z-index: 2,
    ‘непрозорість’: 1
    });
    if(!prefix){
    $slides.eq(activeNdx).animate({‘непрозорість’: 0}, config.fadeDur,
    function(){
    cleanUp();
    });
    } else {
    var styles = {};
    styles[prefix+’transition’] = ‘непрозорість ‘+config.fadeDur+’ms’;
    styles[‘непрозорість’] = 0;
    $slides.eq(activeNdx).css(styles);
    var fadeTimer = setTimeout(function(){
    cleanUp();
    },config.fadeDur);
    };
    };
    function changeSlides(target){
    if(target == ‘next’){
    newSlide = activeSlide + 1;
    if(newSlide > totalSlides — 1){
    newSlide = 0;
    }
    } else if(target == ‘prev’){
    newSlide = activeSlide — 1;
    if(newSlide < 0){
    newSlide = totalSlides — 1;
    };
    } else {
    newSlide = target;
    };
    animateSlides(activeSlide, newSlide);
    };
    for(var i = 0; i < totalSlides; i++){
    $pagerList
    .append(‘

  • ‘+i+’
  • ‘);
    };
    $container.find(‘.page’).bind(‘click’,function(){
    var target = $(this).attr(‘data-target’);
    clearTimeout(slideTimer);
    changeSlides(target);
    });
    var $pagers = $pagerList.find(‘.page’);
    $slides.eq(0).css(‘непрозорість’, 1);
    activeSlide = 0;
    slideTimer = setTimeout(function(){
    changeSlides(‘next’);
    },config.slideDur);
    });
    }
    };
    $.fn.easyFader = function(settings){
    return methods.init.apply(this, arguments);
    };
    })(jQuery);

    Як і всі подібні речі, немає абсолютного «правильно» і «неправильно». Може бути, ви помітили, що ви зробили б по-іншому або могли б поліпшити — і в цьому вся принадність і стимул – в бажанні написати свої власні інструменти. Я сподіваюся, що ви знайшли цю інформацію корисною.

    Це, звичайно, не кінець для EasyFader, так як я маю намір додати купу додаткових функцій, таких як функції зворотного виклику і ще багато параметрів, що настроюються, в надії, що він може стати новим слайд-шоу плагіном «номер один» для всіх моїх проектів. Але на сьогоднішній день, не забудьте перевірити і скопіювати готову версію на GitHub. Якихось 1.2 KB в стислому вигляді!