Accessibility improvements per WCAG 2.1 AA: - Skip-to-content link (TA-1) - ARIA landmarks and roles for nav, main, sections, footer (TA-2) - Accordion keyboard navigation + aria-expanded (TA-3) - Lightbox focus trap + focus management + dialog role (TA-4) - Gallery grid items keyboard accessible (TA-5) - Improved alt texts for all images (TA-6) - Focus-visible styles for all interactive elements (TA-7) - Darker --stone color for WCAG AA contrast compliance (TA-8) Fix #18
170 lines
4.7 KiB
JavaScript
170 lines
4.7 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-header").attr("aria-expanded", "false");
|
||
$(".floor-body").slideUp(300);
|
||
if (!isOpen) {
|
||
item.addClass("open");
|
||
$(this).attr("aria-expanded", "true");
|
||
item.find(".floor-body").slideDown(300);
|
||
}
|
||
});
|
||
|
||
// Accordion keyboard handler (Enter/Space)
|
||
$(".floor-header").on("keydown", function (e) {
|
||
if (e.key === "Enter" || e.key === " ") {
|
||
e.preventDefault();
|
||
$(this).trigger("click");
|
||
}
|
||
});
|
||
|
||
// Lightbox – track last focused element for focus return
|
||
var lightboxTrigger = null;
|
||
|
||
function openLightbox(src) {
|
||
lightboxTrigger = document.activeElement;
|
||
$("#lightboxImg").attr("src", src).attr("alt", "");
|
||
$("#lightbox").addClass("open");
|
||
$("body").css("overflow", "hidden");
|
||
// Set focus to close button
|
||
setTimeout(function () {
|
||
$("#lightboxClose").focus();
|
||
}, 50);
|
||
}
|
||
|
||
function closeLightbox() {
|
||
$("#lightbox").removeClass("open");
|
||
$("body").css("overflow", "");
|
||
// Return focus to trigger
|
||
if (lightboxTrigger) {
|
||
$(lightboxTrigger).focus();
|
||
lightboxTrigger = null;
|
||
}
|
||
}
|
||
|
||
// Lightbox – gallery grid items
|
||
$(document).on("click", ".grid-item", function () {
|
||
var src = $(this).data("img") || $(this).find("img").attr("src");
|
||
openLightbox(src);
|
||
});
|
||
|
||
// Lightbox – floor plan images in Raumaufteilung
|
||
$(document).on("click", ".floor-plan img[data-img]", function () {
|
||
var src = $(this).data("img");
|
||
openLightbox(src);
|
||
});
|
||
|
||
// Lightbox close handlers
|
||
$("#lightboxClose").on("click", function () {
|
||
closeLightbox();
|
||
});
|
||
$("#lightbox").on("click", function (e) {
|
||
if (e.target === this) {
|
||
closeLightbox();
|
||
}
|
||
});
|
||
|
||
// Escape key to close lightbox
|
||
$(document).on("keydown", function (e) {
|
||
if (e.key === "Escape" && $("#lightbox").hasClass("open")) {
|
||
closeLightbox();
|
||
}
|
||
});
|
||
|
||
// Focus trap for lightbox
|
||
$("#lightbox").on("keydown", function (e) {
|
||
if (e.key !== "Tab") return;
|
||
|
||
var focusable = $(this).find("button, [href], input, select, textarea, [tabindex]:not([tabindex='-1'])").filter(":visible");
|
||
if (focusable.length === 0) return;
|
||
|
||
var first = focusable[0];
|
||
var last = focusable[focusable.length - 1];
|
||
|
||
if (e.shiftKey) {
|
||
if (document.activeElement === first) {
|
||
e.preventDefault();
|
||
last.focus();
|
||
}
|
||
} else {
|
||
if (document.activeElement === last) {
|
||
e.preventDefault();
|
||
first.focus();
|
||
}
|
||
}
|
||
});
|
||
|
||
// Gallery keyboard handler (Enter/Space)
|
||
$(document).on("keydown", ".grid-item", function (e) {
|
||
if (e.key === "Enter" || e.key === " ") {
|
||
e.preventDefault();
|
||
$(this).trigger("click");
|
||
}
|
||
});
|
||
|
||
// Form submit – opens email client with pre-filled mailto: link
|
||
$("#contactForm").on("submit", function (e) {
|
||
e.preventDefault();
|
||
|
||
var fname = $("#fname").val().trim();
|
||
var lname = $("#lname").val().trim();
|
||
var email = $("#email").val().trim();
|
||
var phone = $("#phone").val().trim();
|
||
var interest = $("#interest").val();
|
||
var message = $("#message").val().trim();
|
||
|
||
var subject = "Kontaktanfrage: " + interest;
|
||
var body = "Von: " + fname + " " + lname + "\n";
|
||
body += "E-Mail: " + email + "\n";
|
||
if (phone) body += "Telefon: " + phone + "\n";
|
||
body += "Anliegen: " + interest + "\n\n";
|
||
body += message;
|
||
|
||
var mailto =
|
||
"mailto:mki@kies-media.de" +
|
||
"?subject=" + encodeURIComponent(subject) +
|
||
"&body=" + encodeURIComponent(body);
|
||
|
||
window.location.href = mailto;
|
||
|
||
// Show success message
|
||
$("#contactForm").hide();
|
||
$("#formSuccess").fadeIn(400);
|
||
});
|
||
});
|