На сайтах интернет-магазинов (или тому подобных), где на страницах рубрик представлены карточки товаров или услуг, можно встретить мини-слайдеры, в которых показаны превью этих товаров и услуг. При наведении курсора и перемещении его влево-вправо можно посмотреть несколько таких изображений. Чтобы было более понятно, о чем идет речь, зайдите на сайты ozon.ru или realty.yandex.ru.
Из особенностей: на десктопе изображения меняются при перемещении курсора мыши над ним горизонтально, а на мобильных устройствах – если проводить пальцем по изображению.
Исходная структура HTML-кода
<div class="images">
<img src="image">
<img src="image">
<img src="image">
</div>
После выполнения скрипта она обретает следующий вид:<div class="hvr">
<div class="hvr__images">
<div class="images">
<img class="image">
<img class="image">
<img class="image">
</div>
<div class="hvr__sectors">
<div class="hvr__sector"></div>
<div class="hvr__sector"></div>
<div class="hvr__sector"></div>
</div>
</div>
<div class="hvr__dots">
<div class="hvr__dot hvr__dot--active"></div>
<div class="hvr__dot"></div>
<div class="hvr__dot"></div>
</div>
</div>
CSS-код
Есть обязательные стили:.hvr__images { position: relative; } .hvr__sectors { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; } .hvr__sector { flex-grow: 1; }
Также можно добавить дополнительные стили:
- для изображений, чтобы до срабатывания скрипта отображалось только первое изображение;
- для точек, показывающих общее количество изображений и активный слайд.
.images { display: flex; overflow: hidden; } .image { display: block; } .hvr__dots { display: flex; align-items: center; justify-content: center; } .hvr__dot { width: 5px; height: 5px; margin: 10px 2px 0; border-radius: 50%; background: #d6dbe0; } .hvr__dot--active { background: #000; }
Решение на jQuery
(function ($) { $.fn.HvrSlider = function () { return this.each(function () { var el = $(this); if (el.find('img').length > 1) { var hvr = $('<div>', { class: 'hvr', append: [ $('<div>', { class: 'hvr__images', append: $('<div>', { class: 'hvr__sectors', }), }), $('<div>', { class: 'hvr__dots', }), ], insertAfter: el, prepend: el, }); var hvrImages = $('.hvr__images', hvr); var hvrImage = $('img', hvr); var hvrSectors = $('.hvr__sectors', hvr); var hvrDots = $('.hvr__dots', hvr); el.prependTo(hvrImages); hvrImage.each(function () { hvrSectors.prepend('<div class="hvr__sector"></div>'); hvrDots.append('<div class="hvr__dot"></div>'); }); $('.hvr__dot:first', hvrDots).addClass('hvr__dot--active'); var setActiveEl = function (el) { hvrImage.hide().eq(el.index()).show(); $('.hvr__dot', hvrDots).removeClass('hvr__dot--active').eq(el.index()).addClass('hvr__dot--active'); }; $('.hvr__sector', hvrSectors).hover(function () { setActiveEl($(this)); }); hvrSectors.on('touchmove', function (e) { var position = e.originalEvent.changedTouches[0]; var target = document.elementFromPoint(position.clientX, position.clientY); if ($(target).is('.hvr__sector')) { setActiveEl($(target)); } }); } }); }; })(jQuery);
Код для инициализации скрипта:
$('.images').HvrSlider();
Решение на JavaScript
class HvrSlider { constructor(selector) { const elements = document.querySelectorAll(selector); elements.forEach((el) => { if (el.querySelectorAll('img').length > 1) { const hvr = document.createElement('div'); hvr.classList.add('hvr'); const hvrImages = document.createElement('div'); hvrImages.classList.add('hvr__images'); hvr.appendChild(hvrImages); const hvrSectors = document.createElement('div'); hvrSectors.classList.add('hvr__sectors'); hvrImages.appendChild(hvrSectors); const hvrDots = document.createElement('div'); hvrDots.classList.add('hvr__dots'); hvr.appendChild(hvrDots); el.parentNode.insertBefore(hvr, el); hvrImages.prepend(el); const hvrImagesArray = hvr.querySelectorAll('img'); hvrImagesArray.forEach(() => { hvrSectors.insertAdjacentHTML('afterbegin', '<div class="hvr__sector"></div>'); hvrDots.insertAdjacentHTML('afterbegin', '<div class="hvr__dot"></div>'); }); hvrDots.firstChild.classList.add('hvr__dot--active'); const setActiveEl = function (targetEl) { const index = [...hvrSectors.children].indexOf(targetEl); hvrImagesArray.forEach((img, idx) => { if (index == idx) { img.style.display = 'block'; } else { img.style.display = 'none'; } }); hvr.querySelectorAll('.hvr__dot').forEach((dot, idx) => { if (index == idx) { dot.classList.add('hvr__dot--active'); } else { dot.classList.remove('hvr__dot--active'); } }); }; hvrSectors.addEventListener('mouseover', function (e) { if (e.target.matches('.hvr__sector')) { setActiveEl(e.target); } }); hvrSectors.addEventListener('touchmove', function (e) { const position = e.changedTouches[0]; const target = document.elementFromPoint(position.clientX, position.clientY); if (target.matches('.hvr__sector')) { setActiveEl(target); } }); } }); } }
Код для инициализации скрипта:
new HvrSlider('.images');