Сайт Fakel Gym
https://fakelgym.cp.good-production.xyz/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
6.1 KiB
190 lines
6.1 KiB
document.addEventListener('DOMContentLoaded', function () {
|
|
document.querySelectorAll('.gallery-block').forEach(function (block) {
|
|
const blockId = block.getAttribute('data-gallery-id');
|
|
initGalleryBlock(blockId);
|
|
});
|
|
});
|
|
|
|
function initGalleryBlock(blockId) {
|
|
const container = document.getElementById(blockId);
|
|
if (!container) return;
|
|
|
|
const swipers = {};
|
|
const thumbnailSwipers = {};
|
|
const initializedTabs = new Set();
|
|
let lightbox;
|
|
|
|
function initTabSwiper(tabId) {
|
|
if (initializedTabs.has(tabId)) return;
|
|
|
|
const tabContent = container.querySelector(`#tab-${tabId}`);
|
|
if (!tabContent?.querySelector('.gallery-swiper')) return;
|
|
|
|
thumbnailSwipers[tabId] = new Swiper(`#${blockId} #thumbnail-swiper-${tabId}`, {
|
|
slidesPerView: 'auto',
|
|
spaceBetween: 5,
|
|
freeMode: true,
|
|
grabCursor: true,
|
|
watchSlidesProgress: true,
|
|
breakpoints: {
|
|
768: {
|
|
spaceBetween: 24
|
|
}
|
|
}
|
|
});
|
|
|
|
swipers[tabId] = new Swiper(`#${blockId} #swiper-${tabId}`, {
|
|
slidesPerView: 'auto',
|
|
spaceBetween: 12,
|
|
centeredSlides: false,
|
|
initialSlide: 0,
|
|
scrollbar: {
|
|
el: `#swiper-scrollbar-${tabId}`,
|
|
draggable: true,
|
|
},
|
|
grabCursor: true,
|
|
watchSlidesProgress: true,
|
|
lazy: {
|
|
loadPrevNext: true,
|
|
loadOnTransitionStart: true,
|
|
},
|
|
on: {
|
|
slideChange: function () {
|
|
updateThumbnails(tabId, this.realIndex);
|
|
centerThumbnail(tabId, this.realIndex);
|
|
}
|
|
},
|
|
breakpoints: {
|
|
768: {
|
|
spaceBetween: 24
|
|
}
|
|
}
|
|
});
|
|
|
|
initializedTabs.add(tabId);
|
|
}
|
|
|
|
function initLightbox(tabId) {
|
|
const currentSelector = `#${blockId} #tab-${tabId} .glightbox`;
|
|
|
|
if (lightbox?.settings?.selector !== currentSelector) {
|
|
if (lightbox) {
|
|
lightbox.destroy();
|
|
}
|
|
|
|
lightbox = GLightbox({
|
|
selector: currentSelector,
|
|
preload: false,
|
|
touchNavigation: true,
|
|
loop: true
|
|
});
|
|
}
|
|
}
|
|
|
|
function updateThumbnails(tabId, activeIndex) {
|
|
const thumbnails = container.querySelectorAll(`#tab-${tabId} .thumbnail`);
|
|
thumbnails.forEach((thumb, index) => {
|
|
if (index === activeIndex) {
|
|
thumb.classList.remove('opacity-50', 'hover:opacity-80');
|
|
thumb.classList.add('opacity-100', 'active');
|
|
} else {
|
|
thumb.classList.remove('opacity-100', 'active');
|
|
thumb.classList.add('opacity-50', 'hover:opacity-80');
|
|
}
|
|
});
|
|
}
|
|
|
|
function centerThumbnail(tabId, activeIndex) {
|
|
if (thumbnailSwipers[tabId]) {
|
|
thumbnailSwipers[tabId].slideTo(activeIndex);
|
|
}
|
|
}
|
|
|
|
function preloadHeroImage() {
|
|
const activeTab = container.querySelector('.tab-button.active');
|
|
if (!activeTab) return;
|
|
|
|
const tabId = activeTab.getAttribute('data-tab');
|
|
const firstImage = container.querySelector(`#tab-${tabId} .swiper-slide:first-child img`);
|
|
|
|
if (firstImage && firstImage.src) {
|
|
const link = document.createElement('link');
|
|
link.rel = 'preload';
|
|
link.as = 'image';
|
|
link.href = firstImage.src;
|
|
document.head.appendChild(link);
|
|
}
|
|
}
|
|
|
|
function debounce(func, wait) {
|
|
let timeout;
|
|
return (...args) => {
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
};
|
|
}
|
|
|
|
preloadHeroImage();
|
|
|
|
const activeTab = container.querySelector('.tab-button.active');
|
|
if (activeTab) {
|
|
const tabId = activeTab.getAttribute('data-tab');
|
|
initTabSwiper(tabId);
|
|
initLightbox(tabId);
|
|
}
|
|
|
|
container.querySelectorAll('.tab-button').forEach(button => {
|
|
button.addEventListener('click', debounce(() => {
|
|
const tabId = button.getAttribute('data-tab');
|
|
|
|
container.querySelectorAll('.tab-button').forEach(btn =>
|
|
btn.classList.remove('active'));
|
|
button.classList.add('active');
|
|
|
|
container.querySelectorAll('.tab-content').forEach(content => {
|
|
content.classList.remove('block');
|
|
content.classList.add('hidden');
|
|
});
|
|
|
|
const targetTab = container.querySelector(`#tab-${tabId}`);
|
|
targetTab.classList.remove('hidden');
|
|
targetTab.classList.add('block');
|
|
|
|
initTabSwiper(tabId);
|
|
|
|
requestAnimationFrame(() => {
|
|
if (swipers[tabId]) {
|
|
swipers[tabId].update();
|
|
}
|
|
if (thumbnailSwipers[tabId]) {
|
|
thumbnailSwipers[tabId].update();
|
|
}
|
|
});
|
|
|
|
initLightbox(tabId);
|
|
|
|
}, 100));
|
|
});
|
|
|
|
container.addEventListener('click', (e) => {
|
|
const thumbnail = e.target.closest('.thumbnail');
|
|
if (!thumbnail) return;
|
|
|
|
const index = parseInt(thumbnail.getAttribute('data-index'));
|
|
const activeTabContent = container.querySelector('.tab-content.block');
|
|
const tabId = activeTabContent.id.replace('tab-', '');
|
|
|
|
if (swipers[tabId]) {
|
|
swipers[tabId].slideTo(index);
|
|
}
|
|
|
|
updateThumbnails(tabId, index);
|
|
centerThumbnail(tabId, index);
|
|
});
|
|
|
|
window.addEventListener('beforeunload', () => {
|
|
Object.values(swipers).forEach(swiper => swiper?.destroy());
|
|
Object.values(thumbnailSwipers).forEach(swiper => swiper?.destroy());
|
|
if (lightbox) lightbox.destroy();
|
|
});
|
|
} |