Canon

Welche Maße soll dein Akku haben?
(function () { "use strict"; var FIELDS = ["heightMin", "heightMax", "widthMin", "widthMax", "lengthMin", "lengthMax"]; var DEBOUNCE_MS = 300; var debounceTimer = null; var observer = null; function getWidget() { return document.querySelector(".mf-masse-filter"); } function getInput(field) { var widget = getWidget(); return widget ? widget.querySelector('[data-mf-field="' + field + '"]') : null; } function parseNum(raw) { if (raw === null || raw === undefined) { return null; } var v = parseFloat(String(raw).replace(",", ".")); return (isFinite(v) && v > 0) ? v : null; } function readFilter() { var f = {}; for (var i = 0; i < FIELDS.length; i++) { var input = getInput(FIELDS[i]); f[FIELDS[i]] = input ? parseNum(input.value) : null; } return f; } function isActive(f) { for (var i = 0; i < FIELDS.length; i++) { if (f[FIELDS[i]] !== null) { return true; } } return false; } function inRange(value, min, max) { if (min === null && max === null) { return true; } if (!(value > 0)) { return false; } if (min !== null && value < min) { return false; } if (max !== null && value > max) { return false; } return true; } function applyFilter() { var f = readFilter(); var active = isActive(f); var cards = document.querySelectorAll("article.cmp-product-thumb"); var total = 0; var visible = 0; for (var i = 0; i < cards.length; i++) { var card = cards[i]; var wrapper = card.closest("li") || card; total++; if (!active) { wrapper.style.display = ""; visible++; continue; } var dims = card.querySelector(".js-item-dimensions"); var h = dims ? parseFloat(dims.getAttribute("data-height-mm")) : NaN; var w = dims ? parseFloat(dims.getAttribute("data-width-mm")) : NaN; var l = dims ? parseFloat(dims.getAttribute("data-length-mm")) : NaN; var ok = inRange(h, f.heightMin, f.heightMax) && inRange(w, f.widthMin, f.widthMax) && inRange(l, f.lengthMin, f.lengthMax); wrapper.style.display = ok ? "" : "none"; if (ok) { visible++; } } updateStatus(active, visible, total); updateUrl(f, active); } function updateStatus(active, visible, total) { var widget = getWidget(); var status = widget ? widget.querySelector(".mf-status") : null; if (!status) { return; } if (!active) { status.textContent = ""; } else if (visible === 0) { status.textContent = "Keine passenden Artikel auf dieser Seite – ggf. weitere Seiten prüfen oder Filter lockern."; } else { status.textContent = visible + " von " + total + " Artikeln auf dieser Seite passen."; } } function updateUrl(f, active) { try { var url = new URL(window.location.href); for (var i = 0; i < FIELDS.length; i++) { if (active && f[FIELDS[i]] !== null) { url.searchParams.set(FIELDS[i], String(f[FIELDS[i]])); } else { url.searchParams.delete(FIELDS[i]); } } window.history.replaceState(window.history.state, document.title, url.toString()); } catch (e) { /* URL-API nicht verfuegbar: Parameter-Sync entfaellt */ } } function prefillFromUrl() { try { var params = new URL(window.location.href).searchParams; for (var i = 0; i < FIELDS.length; i++) { var value = params.get(FIELDS[i]); var input = getInput(FIELDS[i]); if (input && value !== null && parseNum(value) !== null) { input.value = parseNum(value); } } } catch (e) { /* URL-API nicht verfuegbar */ } } function scheduleApply() { if (debounceTimer) { clearTimeout(debounceTimer); } debounceTimer = setTimeout(applyFilter, DEBOUNCE_MS); } /* Event-Delegation: robust, falls Vue Teile des DOM neu rendert */ document.addEventListener("input", function (e) { if (e.target && e.target.classList && e.target.classList.contains("mf-input")) { scheduleApply(); } }); document.addEventListener("click", function (e) { var btn = e.target && e.target.closest ? e.target.closest(".mf-reset") : null; if (btn) { for (var i = 0; i < FIELDS.length; i++) { var input = getInput(FIELDS[i]); if (input) { input.value = ""; } } applyFilter(); } }); function startObserver() { /* Karten werden per intersect-Komponente lazy hydratisiert: Filter erneut anwenden, wenn neue Karten im DOM auftauchen. Beobachtet nur childList (keine Attribute), unsere style-Aenderungen triggern den Observer daher nicht. */ var list = document.querySelector("ul.product-list") || document.body; if (observer) { observer.disconnect(); } observer = new MutationObserver(function () { var f = readFilter(); if (isActive(f)) { scheduleApply(); } }); observer.observe(list, { childList: true, subtree: true }); } function init() { if (!getWidget()) { return; } prefillFromUrl(); var f = readFilter(); if (isActive(f)) { applyFilter(); } startObserver(); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); } })();