201 lines
6.4 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
// --- Hero Carousel Logic ---
const heroTrack = document.querySelector('.hero-track');
const heroSlides = document.querySelectorAll('.hero-slide');
const preventBtn = document.querySelector('.slider-arrow.prev');
const nextBtn = document.querySelector('.slider-arrow.next');
const dots = document.querySelectorAll('.dot');
let currentSlide = 0;
const totalSlides = heroSlides.length;
let autoplayInterval;
function updateCarousel() {
heroTrack.style.transform = `translateX(-${currentSlide * 100}%)`;
dots.forEach((dot, index) => {
dot.classList.toggle('active', index === currentSlide);
});
}
function nextSlide() {
currentSlide = (currentSlide + 1) % totalSlides;
updateCarousel();
}
function prevSlide() {
currentSlide = (currentSlide - 1 + totalSlides) % totalSlides;
updateCarousel();
}
// Controls
if(nextBtn) nextBtn.addEventListener('click', () => {
nextSlide();
resetAutoplay();
});
if(preventBtn) preventBtn.addEventListener('click', () => {
prevSlide();
resetAutoplay();
});
dots.forEach((dot, index) => {
dot.addEventListener('click', () => {
currentSlide = index;
updateCarousel();
resetAutoplay();
});
});
// Autoplay
function startAutoplay() {
autoplayInterval = setInterval(nextSlide, 6000);
}
function resetAutoplay() {
clearInterval(autoplayInterval);
startAutoplay();
}
// Hover pause
const heroSlider = document.querySelector('.hero-slider');
if (heroSlider) {
heroSlider.addEventListener('mouseenter', () => clearInterval(autoplayInterval));
heroSlider.addEventListener('mouseleave', startAutoplay);
startAutoplay();
}
// --- Header Scroll Effect ---
const header = document.querySelector('.site-header');
window.addEventListener('scroll', () => {
if (window.scrollY > 50) {
header.classList.add('scrolled');
} else {
header.classList.remove('scrolled');
}
});
// --- Filter Tabs Logic (Client-side simulation) ---
const tabBtns = document.querySelectorAll('.tab-btn');
const productGrid = document.querySelector('.product-grid-container');
const productItems = document.querySelectorAll('.product-item');
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
// Active State
tabBtns.forEach(b => {
b.classList.remove('active');
b.setAttribute('aria-selected', 'false');
});
btn.classList.add('active');
btn.setAttribute('aria-selected', 'true');
// Filter Logic
const filter = btn.dataset.filter;
// Animation: Fade out
productGrid.style.opacity = '0';
productGrid.style.transform = 'translateY(10px)';
productGrid.style.transition = 'all 0.2s';
setTimeout(() => {
productItems.forEach(item => {
if (filter === 'all' || item.dataset.category === filter) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
});
// Fade in
productGrid.style.opacity = '1';
productGrid.style.transform = 'translateY(0)';
}, 200);
});
});
// --- Mobile Menu Toggle ---
// --- Mobile Drawer Toggle ---
(() => {
const btn = document.querySelector('.mobile-menu-btn');
const drawer = document.querySelector('.mobile-drawer');
const overlay = document.querySelector('.mobile-drawer-overlay');
if (!btn || !drawer || !overlay) return;
const open = () => {
drawer.classList.add('is-open');
overlay.hidden = false;
drawer.setAttribute('aria-hidden', 'false');
btn.setAttribute('aria-expanded', 'true');
document.body.classList.add('is-drawer-open');
};
const close = () => {
drawer.classList.remove('is-open');
overlay.hidden = true;
drawer.setAttribute('aria-hidden', 'true');
btn.setAttribute('aria-expanded', 'false');
document.body.classList.remove('is-drawer-open');
};
btn.addEventListener('click', () => {
drawer.classList.contains('is-open') ? close() : open();
});
// overlay 클릭 or 닫기 버튼
document.querySelectorAll('[data-drawer-close]').forEach(el => {
el.addEventListener('click', close);
});
// ESC 닫기
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && drawer.classList.contains('is-open')) close();
});
})();
// --- Sub Hero Carousel ---
(function initSubHero(){
const wrap = document.querySelector('.subhero-inner');
if(!wrap) return;
const track = wrap.querySelector('.subhero-track');
const slides = wrap.querySelectorAll('.subhero-slide');
const prev = wrap.querySelector('.subhero-arrow.prev');
const next = wrap.querySelector('.subhero-arrow.next');
const dots = wrap.querySelectorAll('.subhero-dot');
let idx = 0;
const total = slides.length;
if(total <= 1) return;
const render = () => {
track.style.transform = `translateX(-${idx * 100}%)`;
dots.forEach((d,i)=>d.classList.toggle('active', i===idx));
};
const goNext = () => { idx = (idx + 1) % total; render(); };
const goPrev = () => { idx = (idx - 1 + total) % total; render(); };
let t = setInterval(goNext, 6000);
const reset = () => { clearInterval(t); t = setInterval(goNext, 6000); };
next?.addEventListener('click', ()=>{ goNext(); reset(); });
prev?.addEventListener('click', ()=>{ goPrev(); reset(); });
dots.forEach(d => d.addEventListener('click', ()=>{
idx = Number(d.dataset.index || 0);
render(); reset();
}));
wrap.addEventListener('mouseenter', ()=>clearInterval(t));
wrap.addEventListener('mouseleave', ()=>{ t = setInterval(goNext, 6000); });
render();
})();
});