Как создать привлекательную отзывчивую галерею изображений с помощью slick.js
() translation by (you can also view the original English article)
В этом руководстве мы будем использовать популярный jQuery плагин slick.js, чтобы создать привлекательную отзывчивую галерею изображений. Вот галерея, которую мы собираемся создать:
Обязательно посмотрите полноэкранную версию и измените размер окна браузера, чтобы увидеть, как изменяется макет в зависимости от размера экрана.
Что такое slick.js?
Slick.js - хорошо известный плагин jQuery, созданный Кеном Уилером, который позволяет создавать красивые отзывчивые слайдеры. Чтобы лучше понять, что может предложить этот плагин, ознакомьтесь с документацией.
К счастью, он работает не только во всех современных браузерах, но и в более старых, таких как IE 8+.
Наконец, вы можете взглянуть на версию для WordPress.
Начало работы с slick.js
Чтобы начать работу с slick, начните с загрузки и установки следующих файлов в вашем проекте:
- jQuery (≥1.7)
-
slick.css
или его минифицированная версия
-
Slick.js
или его минифицированная версия
При желании вы можете импортировать файл slick-theme.css
.
Вы можете получить копию соответствующих файлов, посетив репозиторий Github, используя диспетчер пакетов (например, npm) или загрузив необходимые ресурсы через CDN (например, cdnjs). В этом руководстве я использую последний вариант.
Кроме того, я включил Babel для компиляции кода ES6 до ES5 и Lodash для использования функции debounce
(мы будем использовать это позже).
Имея это в виду, если вы посмотрите на вкладку Settings нашего демо в codepen, вы увидите, что я включил один внешний CSS-файл и три внешних файла JavaScript.






1. HTML
На этом этапе важно понять структуру нашей страницы. Самое главное, мы определим две карусели, которые имеют одинаковые изображения и синхронизированы (как - мы обсудим позже). Размеры изображения составляют 860 x 550 пикселей, хотя в ваших собственных проектах они могут быть другими.
Наконец, в качестве части второй карусели мы укажем стрелки навигации, а также элемент, который отслеживает общее количество слайдов.
Вот необходимая структура для нашей демонстрационной страницы:
1 |
<div class="loading">Carousel is loading...</div> |
2 |
<div class="container"> |
3 |
<div class="synch-carousels"> |
4 |
|
5 |
<div class="left child"> |
6 |
<div class="gallery"> |
7 |
<div class="item"> |
8 |
<img src="IMG_SRC" alt=""> |
9 |
</div>
|
10 |
<!-- 4 more images here -->
|
11 |
</div>
|
12 |
</div><!--/left--> |
13 |
|
14 |
<div class="right child"> |
15 |
<div class="gallery2"> |
16 |
<div class="item"> |
17 |
<img src="IMG_SRC" alt=""> |
18 |
</div>
|
19 |
<!-- 4 more images here -->
|
20 |
</div>
|
21 |
<div class="nav-arrows"> |
22 |
<button class="arrow-left"> |
23 |
<!--svg here-->
|
24 |
</button>
|
25 |
<button class="arrow-right"> |
26 |
<!--svg here-->
|
27 |
</button>
|
28 |
</div>
|
29 |
<div class="photos-counter"> |
30 |
<span></span><span></span>
|
31 |
</div>
|
32 |
</div><!--/right--> |
33 |
|
34 |
</div>
|
35 |
</div>
|
2. CSS
В общей сложности наша галерея должна иметь четыре разных вида, в зависимости от размера окна просмотра. Давайте сделаем их, следуя подходу mobile-first.
Когда окно браузера меньше 480 пикселей, оно будет выглядеть так, что видно только вторую карусель и навигационную панель:



Затем на экранах между 480px и 768px она должна выглядеть следующим образом, два эскиза под основным слайдом:



Далее, на экранах между 769px и 1023px, мы представим третий эскиз:



Наконец, на больших экранах (≥1024px), она должна выглядеть следующим образом, миниатюры появляются сбоку (обратите внимание, что они не полностью соответствуют этому изображению):



Все приведенные выше случаи сделаны в медиа-запросах, показанных ниже:
1 |
.synch-carousels { |
2 |
position: relative; |
3 |
display: flex; |
4 |
flex-wrap: wrap; |
5 |
justify-content: space-between; |
6 |
}
|
7 |
|
8 |
.synch-carousels > * { |
9 |
width: 100%; |
10 |
}
|
11 |
|
12 |
.synch-carousels .right { |
13 |
order: -1; |
14 |
}
|
15 |
|
16 |
.synch-carousels .left { |
17 |
overflow: hidden; |
18 |
}
|
19 |
|
20 |
.synch-carousels .gallery { |
21 |
display: none; |
22 |
}
|
23 |
|
24 |
.synch-carousels .gallery .slick-list { |
25 |
height: auto !important; |
26 |
margin: 0 -20px; |
27 |
}
|
28 |
|
29 |
.synch-carousels .gallery .slick-slide { |
30 |
margin: 0 20px; |
31 |
}
|
32 |
|
33 |
@media screen and (min-width: 480px) { |
34 |
.synch-carousels .right { |
35 |
margin-bottom: 20px; |
36 |
}
|
37 |
|
38 |
.synch-carousels .gallery { |
39 |
display: block; |
40 |
}
|
41 |
}
|
42 |
|
43 |
@media screen and (min-width: 1024px) { |
44 |
.synch-carousels .right { |
45 |
position: relative; |
46 |
width: calc(100% - 230px); |
47 |
margin-bottom: 0; |
48 |
order: 2; |
49 |
}
|
50 |
|
51 |
.synch-carousels .left { |
52 |
width: 210px; |
53 |
}
|
54 |
|
55 |
.synch-carousels .gallery .slick-slide { |
56 |
margin: 0 0 20px 0; |
57 |
}
|
58 |
|
59 |
.synch-carousels .gallery .slick-list { |
60 |
margin: 0; |
61 |
}
|
62 |
}
|
Обратите внимание на правило !important
. Оно переопределяет встроенный стиль.
3. JavaScript
Давайте теперь обратим наше внимание на вещи, связанные с JavaScript.
Кэширование селекторов
Когда DOM готов, хорошей практикой будет кэшировать некоторые часто используемые селекторы:
1 |
const $left = $(".left"); |
2 |
const $gl = $(".gallery"); |
3 |
const $gl2 = $(".gallery2"); |
4 |
const $photosCounterFirstSpan = $(".photos-counter span:nth-child(1)"); |
Инициализация каруселей
Затем мы инициализируем и синхронизируем наши две карусели. Код, отвечающий за это, выглядит следующим образом:
1 |
$gl.slick({ |
2 |
rows: 0, |
3 |
slidesToShow: 2, |
4 |
arrows: false, |
5 |
draggable: false, |
6 |
useTransform: false, |
7 |
mobileFirst: true, |
8 |
responsive: [ |
9 |
{
|
10 |
breakpoint: 768, |
11 |
settings: { |
12 |
slidesToShow: 3 |
13 |
}
|
14 |
},
|
15 |
{
|
16 |
breakpoint: 1023, |
17 |
settings: { |
18 |
slidesToShow: 1, |
19 |
vertical: true |
20 |
}
|
21 |
}
|
22 |
]
|
23 |
});
|
24 |
|
25 |
$gl2.slick({ |
26 |
rows: 0, |
27 |
useTransform: false, |
28 |
prevArrow: ".arrow-left", |
29 |
nextArrow: ".arrow-right", |
30 |
fade: true, |
31 |
asNavFor: $gl |
32 |
});
|
Несомненно, лучший способ понять, как работает этот код, это прочитать документацию по slick. Однако, позвольте мне объяснить здесь две важные вещи:
- Опция конфигурации
asNavFor
позволяет нам синхронизировать карусели и использовать одну как навигацию для другой. - По умолчанию slick использует преобразования CSS. Однако, в нашем случае мы отключили их, установив
useTransform: false
. Это происходит потому, что они вызывают небольшое мерцание в первом слайде первой карусели на больших экранах (мы могли бы отключить их только для первой карусели).
Отображение и настройка макета галереи
Наша галерея должна быть видна только тогда, когда все ресурсы страницы готовы. Первоначально появляется дополнительный прелоадер - снова обращаемся к разметке, он выглядит так:
1 |
<div class="loading">Carousel is loading...</div> |
На этом этапе мы должны снова подумать о желаемом макете галереи на больших экранах. Если вы посмотрите на соответствующие скриншоты, вы заметите, что обе карусели имеют одинаковые высоты. Чтобы достичь желаемого поведения, мы должны написать собственный код JavaScript (после нашего CSS). Этот код будет динамически устанавливать высоту первой карусели, равной высоте второй (или наоборот).
Зная вышеприведенные требования, вот код, который запускается, когда вся страница готова:
1 |
$(window).on("load", () => { |
2 |
handleCarouselsHeight(); |
3 |
setTimeout(() => { |
4 |
$(".loading").fadeOut(); |
5 |
$("body").addClass("over-visible"); |
6 |
}, 300); |
7 |
});
|
И вот объявление функции handleCarouselsHeight:
1 |
function handleCarouselsHeight() { |
2 |
if (window.matchMedia("(min-width: 1024px)").matches) { |
3 |
const gl2H = $(".gallery2)").height(); |
4 |
$left.css("height", gl2H); |
5 |
} else { |
6 |
$left.css("height", "auto"); |
7 |
}
|
8 |
}
|
Когда страница загружается, галерея отлично работает. Но она также должна работать так, как ожидается, когда окно браузера будет изменено.
Код, относящийся к этой конкретной ситуации, показан ниже:
1 |
$(window).on( |
2 |
"resize", |
3 |
_.debounce(() => { |
4 |
handleCarouselsHeight(); |
5 |
}, 200) |
6 |
);
|
Обратите внимание, что обработчик события завернут внутрь функции debounce
. Это Lodash функция, которая помогает нам ограничить количество вызовов этого обработчика.
Работа с событиями и методами slick
Теперь, когда мы успешно реализовали основные функции нашей галереи, давайте сделаем еще один шаг и создадим несколько дополнительных вещей.
Во-первых, в верхнем правом углу второй карусели мы показываем текущий слайд и общее количество слайдов.



Для этого мы используем события slick init
и afterChange
.
Вот соответствующий код:
1 |
/*you have to bind init event before slick's initialization (see demo) */
|
2 |
gl2.on("init", (event, slick) => { |
3 |
$photosCounterFirstSpan.text(`${slick.currentSlide + 1}/`); |
4 |
$(".photos-counter span:nth-child(2)").text(slick.slideCount); |
5 |
});
|
6 |
|
7 |
$gl2.on("afterChange", (event, slick, currentSlide) => { |
8 |
$photosCounterFirstSpan.text(`${slick.currentSlide + 1}/`); |
9 |
});
|
В качестве дополнительного улучшения каждый раз, когда мы нажимаем на слайд первой карусели, связанный с ним слайд второй карусели должен быть активным. Благодаря методу slickGoTo
от slick мы можем реализовать эту функциональность.
Вот соответствующий код:
1 |
$(".gallery .item").on("click", function() { |
2 |
const index = $(this).attr("data-slick-index"); |
3 |
$gl2.slick("slickGoTo", index); |
4 |
});
|
4. Поддерживаемые браузеры
Это демо должно хорошо работать во всех последних браузерах, и вы спокойно можете использовать его в своих проектах.
Я столкнулся только с одной небольшой ошибкой в некоторых браузерах (Firefox, Edge) при тестировании демо на больших экранах. Когда вы нажимаете на стрелки навигации, все слайды первой карусели, кроме первой, не достигают верхнего края их родителя и оставляют зазор в один пиксель:



И последнее, но не менее важное: небольшие изменения и настройки могут потребоваться по мере изменения размера окна в зависимости от ваших потребностей.
Заключение
В этом руководстве мы использовали slick.js и смогли создать красивую отзывчивую галерею. Надеюсь, теперь вы готовы попробовать эту реализацию в своих проектах. Если это произойдет, не стесняйтесь делиться ссылкой на проект в комментариях ниже!
Еще проекты JavaScript для оживления ваших сайтов
- ПроизводительностьПовышение производительности: Как загружать изображения, используя in-view.jsLouie Rootfield
- FlickityСоздание слайдера с помощью Metafizzy’s FlickityThoriq Firdaus
- jQueryНебольшой совет: анимация прокрутки с помощью fullPage.js и Animate.cssGeorge Martsoukos
- JavaScriptКак создать слайдер с разделенным экраном на JavaScriptAdi Purdila