All checks were successful
Deploy Feature Branch to Test / deploy (push) Successful in 24s
- Use .off('error') to prevent stacking error handlers
- Simplify fallback logic: only replace .webp → .png on error
- Prevents infinite error loops
132 lines
3.9 KiB
JavaScript
132 lines
3.9 KiB
JavaScript
$(function () {
|
||
// Navbar scroll
|
||
$(window).on("scroll", function () {
|
||
if ($(this).scrollTop() > 60) $("#navbar").addClass("scrolled");
|
||
else $("#navbar").removeClass("scrolled");
|
||
});
|
||
|
||
// Hero animation on load
|
||
setTimeout(function () {
|
||
$("#heroContent").addClass("visible");
|
||
$("#heroBg").addClass("loaded");
|
||
}, 200);
|
||
|
||
// Scroll animations
|
||
function checkVisible() {
|
||
$(".fact, [data-animate]").each(function () {
|
||
var el = $(this);
|
||
var top = el.offset().top;
|
||
var windowBottom = $(window).scrollTop() + $(window).height();
|
||
if (windowBottom > top + 60) {
|
||
el.addClass("visible");
|
||
el.css({ opacity: 1, transform: "translateY(0)" });
|
||
}
|
||
});
|
||
}
|
||
$("[data-animate]").css({
|
||
opacity: 0,
|
||
transform: "translateY(30px)",
|
||
transition: "opacity 0.8s ease, transform 0.8s ease",
|
||
});
|
||
$(window).on("scroll", checkVisible);
|
||
checkVisible();
|
||
|
||
// Floor accordion
|
||
$(".floor-header").on("click", function () {
|
||
var item = $(this).closest(".floor-item");
|
||
var isOpen = item.hasClass("open");
|
||
$(".floor-item").removeClass("open");
|
||
$(".floor-body").slideUp(300);
|
||
if (!isOpen) {
|
||
item.addClass("open");
|
||
item.find(".floor-body").slideDown(300);
|
||
}
|
||
});
|
||
|
||
// Lightbox – gallery grid items
|
||
$(document).on("click", ".grid-item", function () {
|
||
var src = $(this).data("img") || $(this).find("img").attr("src");
|
||
$("#lightboxImg").off("error").on("error", function () {
|
||
// WebP fallback: try original format
|
||
if ($(this).attr('src').endsWith('.webp')) {
|
||
$(this).attr('src', src.replace(/\.webp$/, '.png'));
|
||
}
|
||
});
|
||
$("#lightboxImg").attr("src", src);
|
||
$("#lightbox").addClass("open");
|
||
$("body").css("overflow", "hidden");
|
||
});
|
||
|
||
// Lightbox – floor plan images in Raumaufteilung
|
||
$(document).on("click", ".floor-plan img[data-img]", function () {
|
||
var src = $(this).data("img");
|
||
$("#lightboxImg").off("error").on("error", function () {
|
||
if ($(this).attr('src').endsWith('.webp')) {
|
||
$(this).attr('src', src.replace(/\.webp$/, '.png'));
|
||
}
|
||
});
|
||
$("#lightboxImg").attr("src", src);
|
||
$("#lightbox").addClass("open");
|
||
$("body").css("overflow", "hidden");
|
||
});
|
||
$("#lightboxClose, #lightbox").on("click", function (e) {
|
||
if (e.target === this) {
|
||
$("#lightbox").removeClass("open");
|
||
$("body").css("overflow", "");
|
||
}
|
||
});
|
||
$(document).on("keydown", function (e) {
|
||
if (e.key === "Escape") {
|
||
$("#lightbox").removeClass("open");
|
||
$("body").css("overflow", "");
|
||
}
|
||
});
|
||
|
||
// Form submit is handled server-side by PHP – no JS intervention needed.
|
||
});
|
||
|
||
// Mobile hamburger menu (vanilla JS)
|
||
(function () {
|
||
var hamburger = document.querySelector(".nav-hamburger");
|
||
var nav = document.getElementById("navbar");
|
||
var overlay = document.querySelector(".nav-mobile-overlay");
|
||
var links = nav ? nav.querySelectorAll(".nav-links a") : [];
|
||
|
||
function toggleMenu() {
|
||
var isOpen = hamburger.classList.toggle("active");
|
||
nav.classList.toggle("mobile-open", isOpen);
|
||
if (overlay) overlay.classList.toggle("active", isOpen);
|
||
hamburger.setAttribute("aria-expanded", isOpen);
|
||
document.body.style.overflow = isOpen ? "hidden" : "";
|
||
}
|
||
|
||
function closeMenu() {
|
||
hamburger.classList.remove("active");
|
||
nav.classList.remove("mobile-open");
|
||
if (overlay) overlay.classList.remove("active");
|
||
hamburger.setAttribute("aria-expanded", "false");
|
||
document.body.style.overflow = "";
|
||
}
|
||
|
||
if (hamburger) {
|
||
hamburger.addEventListener("click", toggleMenu);
|
||
}
|
||
|
||
if (overlay) {
|
||
overlay.addEventListener("click", closeMenu);
|
||
}
|
||
|
||
links.forEach(function (link) {
|
||
link.addEventListener("click", closeMenu);
|
||
});
|
||
|
||
document.addEventListener("keydown", function (e) {
|
||
if (e.key === "Escape") closeMenu();
|
||
});
|
||
|
||
// Close on resize to desktop
|
||
window.addEventListener("resize", function () {
|
||
if (window.innerWidth > 900) closeMenu();
|
||
});
|
||
})();
|