Предположим, нужно крутить несколько фотогалерей в слайдере. Например, миниатюры записей из категорий. Таким образом, главный слайдер будет ротировать категории, а тело каждого слайда будет содержать слайдер записей. Чтобы было интереснее, сделаем даже два слайдера записей в каждом слайде категорий. Начнём с макета.
Будем использовать Swiper slider. HTML шаблон у него такой:
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
...
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</div>
Главный слайдер
Для главного слайдера, согласно макету, пагинация и скроллбар нам не нужны, поэтому упрощаем до:
<div class="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
Так как я являюсь одним из лучших специалистов по WordPress, сделаю сразу вывод категорий, чтобы работать с кодом одного слайда в цикле категорий. Так будет нагляднее.
<div class="swiper">
<div class="swiper-wrapper">
<?php
$categories = get_categories();
if( $categories ){
foreach( $categories as $cat ){
?>
<div class="swiper-slide">
<div class="cat-name"><?= $cat->name ?></div>
<div class="cat-gallery"></div>
</div>
<?php
}
}
?>
</div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
Внутренние слайдеры
Добавим их внутрь элементов с классом swiper-slide. Шаблон будет таким же, только у слайдера миниатюр не будет стрелок. Также, чтобы прописать различные стили и поведение для стрелок главного слайдера и внутреннего слайдера фото, добавим к навигации главного слайдера класс parent, а к навигации фото — класс child.
<div class="swiper parent-slider">
<div class="swiper-wrapper">
<?php
$categories = get_categories();
if( $categories ){
foreach( $categories as $cat ){
?>
<div class="swiper-slide">
<div class="cat-name"><?= $cat->name ?></div>
<div class="cat-gallery">
<div class="swiper child-slider-photos">
<div class="swiper-wrapper">
<?php
$photos = get_posts([
'category' => $cat->term_id,
'exclude' => get_the_ID(),
]);
foreach ($photos as $photo) {
?>
<div class="swiper-slide">
<a href="<?= get_permalink( $photo->ID ) ?>">
<img src="<?= get_the_post_thumbnail_url( $photo->ID, 'large' ); ?>" alt="<?= get_the_title( $photo->ID ) ?>">
</a>
</div>
<?php
}
wp_reset_postdata();
?>
</div>
<div class="swiper-button-prev child"></div>
<div class="swiper-button-next child"></div>
</div>
<div class="swiper child-slider-thumbs">
<div class="swiper-wrapper">
<?php
foreach ($photos as $photo) {
?>
<div class="swiper-slide">
<img src="<?= get_the_post_thumbnail_url( $photo->ID, 'thumbnails' ); ?>" alt="<?= get_the_title( $photo->ID ) ?>">
</div>
<?php
}
wp_reset_postdata();
?>
</div>
</div>
</div>
</div>
<?php
}
}
?>
</div>
<div class="swiper-button-prev parent"></div>
<div class="swiper-button-next parent"></div>
</div>
Итак, слайдеры — это элементы с классом swiper. Чтобы инициализирующий javascript смог отличить главный слайдер от внутренних и внутренние между собой, добавил различные классы к swiper.
- parent-slider — для главного;
- child-slider-photos — для фото;
- child-slider-thumbs — для миниатюр.
На этом, работа с HTML закончена.
Инициализация нескольких слайдеров на одной странице
Ради этого и пишу. Как сделать несколько слайдеров на одной странице без присвоения каждому уникального идентификатора и соответственного ему JS кода? Будем искать элементы по классу и циклически инициализировать их поочередно.
const parentSlider = new Swiper(".parent-slider", {
noSwiping: true,
navigation: {
nextEl: ".swiper-button-next.parent",
prevEl: ".swiper-button-prev.parent",
},
});
const catGalleryItems = document.querySelectorAll(".cat-gallery");
let photos = [];
let thumbs = [];
catGalleryItems.forEach((catGallery, index) => {
thumbs[index] = new Swiper(catGallery.querySelector(".child-slider-thumbs"), {
spaceBetween: 10,
slidesPerView: 4,
freeMode: true,
watchSlidesProgress: true,
});
photos[index] = new Swiper(catGallery.querySelector(".child-slider-photos"), {
lazy: true,
thumbs: {
swiper: thumbs[index],
},
navigation: {
nextEl: ".swiper-button-next.child",
prevEl: ".swiper-button-prev.child",
},
});
});
Чтобы разнести навигацию слайдеров подальше друг от друга, добавлю стили:
.parent-slider {
width: 640px;
}
.child-slider-photos {
margin: 0 0 10px;
}
.child-slider-thumbs .swiper-slide {
opacity: 0.4;
}
.child-slider-thumbs .swiper-slide-thumb-active {
opacity: 1;
}
.cat-name {
font-size: 36px;
font-weight: bold;
color: #000;
line-height: 50px;
margin: 0 0 20px;
}
.swiper-button-prev.parent,
.swiper-button-next.parent {
color: #000;
top: 23px !important;
}
.swiper-button-prev.parent {
left: unset !important;
right: 50px !important;
}
.swiper-button-next.parent {
right: 0 !important;
}
Вот что получилось.

