tischlerei-staffenberger/js/script.js

186 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Tischlerei Staffenberger - Main JavaScript
* Handles navigation active state, gallery filtering, and lightbox on Bilder page.
*/
(function () {
'use strict';
/**
* Set active state on the current page's nav link based on URL pathname.
*/
function setActiveNav() {
var navLinks = document.querySelectorAll('.main-nav a');
var path = window.location.pathname;
var page = path.split('/').pop() || 'index.html';
navLinks.forEach(function (link) {
var href = link.getAttribute('href');
if (!href) return;
var linkPage = href.split('/').pop() || 'index.html';
if (linkPage === page || (page === '' && linkPage === 'index.html')) {
link.classList.add('active');
} else {
link.classList.remove('active');
}
});
}
/**
* Gallery filter: show/hide items by data-category.
*/
function initGalleryFilter() {
var filters = document.querySelectorAll('.gallery-filters button');
var items = document.querySelectorAll('.gallery-item');
if (!filters.length || !items.length) return;
filters.forEach(function (btn) {
btn.addEventListener('click', function () {
var category = this.getAttribute('data-filter');
// Update active button
filters.forEach(function (b) {
b.classList.toggle('active', b === btn);
});
// Show/hide items
items.forEach(function (item) {
var itemCategory = item.getAttribute('data-category');
var show = category === 'all' || itemCategory === category;
item.style.display = show ? '' : 'none';
});
});
});
}
/**
* Lightbox on Bilder page: open on gallery image click, navigate with swipe / arrow
* keys / prev+next buttons, close via X, backdrop or ESC.
* Respects the active gallery filter only visible items are part of the sequence.
*/
function initLightbox() {
var lightbox = document.getElementById('lightbox');
var lightboxImg = document.getElementById('lightbox-img');
if (!lightbox || !lightboxImg) return;
var closeBtn = lightbox.querySelector('.lightbox-close');
var backdrop = lightbox.querySelector('.lightbox-backdrop');
var prevBtn = lightbox.querySelector('.lightbox-prev');
var nextBtn = lightbox.querySelector('.lightbox-next');
var currentIndex = 0;
var sequence = []; // visible gallery links at the time the lightbox was opened
function getVisibleLinks() {
return Array.from(document.querySelectorAll('.gallery-item'))
.filter(function (item) { return item.style.display !== 'none'; })
.map(function (item) { return item.querySelector('.gallery-image-link'); })
.filter(Boolean);
}
function showImage(index) {
var link = sequence[index];
if (!link) return;
currentIndex = index;
lightboxImg.src = link.getAttribute('data-lightbox-src') || link.getAttribute('href');
lightboxImg.alt = link.getAttribute('data-lightbox-alt') || '';
var multiple = sequence.length > 1;
if (prevBtn) prevBtn.hidden = !multiple;
if (nextBtn) nextBtn.hidden = !multiple;
}
function navigate(dir) {
showImage((currentIndex + dir + sequence.length) % sequence.length);
}
function openLightbox(index) {
sequence = getVisibleLinks();
showImage(index);
lightbox.classList.add('is-open');
document.addEventListener('keydown', onKeydown);
}
function closeLightbox() {
lightbox.classList.remove('is-open');
document.removeEventListener('keydown', onKeydown);
}
function onKeydown(e) {
if (e.key === 'Escape') closeLightbox();
if (e.key === 'ArrowRight') navigate(1);
if (e.key === 'ArrowLeft') navigate(-1);
}
// Touch swipe
var touchStartX = 0;
lightbox.addEventListener('touchstart', function (e) {
touchStartX = e.changedTouches[0].clientX;
}, { passive: true });
lightbox.addEventListener('touchend', function (e) {
var dx = e.changedTouches[0].clientX - touchStartX;
if (Math.abs(dx) > 50) navigate(dx < 0 ? 1 : -1);
}, { passive: true });
// Open on gallery click
document.querySelectorAll('.gallery-image-link').forEach(function (link) {
link.addEventListener('click', function (e) {
e.preventDefault();
var visibles = getVisibleLinks();
var idx = visibles.indexOf(link);
openLightbox(idx >= 0 ? idx : 0);
});
});
if (prevBtn) prevBtn.addEventListener('click', function () { navigate(-1); });
if (nextBtn) nextBtn.addEventListener('click', function () { navigate(1); });
if (closeBtn) closeBtn.addEventListener('click', closeLightbox);
if (backdrop) backdrop.addEventListener('click', closeLightbox);
}
/**
* "Request" buttons on shop page open mailto with product name in subject.
*/
function initShopRequests() {
var requestBtns = document.querySelectorAll('.product-card .btn[data-product]');
requestBtns.forEach(function (btn) {
btn.addEventListener('click', function (e) {
var product = this.getAttribute('data-product');
if (product) {
// Open mail with subject line (no real checkout) replace email with your address
var mailto = 'mailto:info@tischlerei-staffenberger.example?subject=Anfrage%20Produkt%3A%20' + encodeURIComponent(product);
window.location.href = mailto;
}
});
});
}
/**
* Shop empty state: show message when no products are present.
*/
function initShopEmptyState() {
var emptyMsg = document.getElementById('shop-empty-message');
var grid = document.getElementById('shop-grid');
if (!emptyMsg || !grid) return;
var hasCards = grid.querySelectorAll('.product-card').length > 0;
emptyMsg.hidden = hasCards;
}
/**
* Run on DOM ready.
*/
function init() {
setActiveNav();
initGalleryFilter();
initLightbox();
initShopRequests();
initShopEmptyState();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();