1(function () { 2 'use strict'; 3 4 /** 5 * Erzeugt ein zugängliches Modal (Fokus-Management, ESC, Focus-Trap, 6 * Overlay-Klick, Scroll-Sperre). 7 * 8 * options.overlayId â ID des Overlays 9 * options.dialogId â ID der Dialog-Box 10 * options.closeIds â Array mit IDs von SchlieÃen-Buttons 11 * options.onOpen â optional: function (triggerElement) {}, wird vor dem Anzeigen aufgerufen 12 */ 13 function createModal(options) { 14 var overlay = document.getElementById(options.overlayId); 15 var dialog = document.getElementById(options.dialogId); 16 17 if (!overlay || !dialog) { 18 return null; 19 } 20 21 var lastFocusedElement = null; 22 23 // Alle fokussierbaren Elemente innerhalb des Dialogs ermitteln 24 function getFocusableElements() { 25 var selectors = [ 26 'a[href]', 27 'button:not([disabled])', 28 'textarea:not([disabled])', 29 'input:not([disabled])', 30 'select:not([disabled])', 31 '[tabindex]:not([tabindex="-1"])' 32 ]; 33 return Array.prototype.slice.call( 34 dialog.querySelectorAll(selectors.join(',')) 35 ); 36 } 37 38 function onKeydown(event) { 39 // ESC schlieÃt das Popup 40 if (event.key === 'Escape' || event.key === 'Esc') { 41 event.preventDefault(); 42 close(); 43 return; 44 } 45 46 // Fokus innerhalb des Dialogs halten (Focus-Trap) via Tab 47 if (event.key === 'Tab') { 48 var focusable = getFocusableElements(); 49 if (!focusable.length) return; 50 51 var first = focusable[0]; 52 var last = focusable[focusable.length - 1]; 53 54 if (event.shiftKey && document.activeElement === first) { 55 event.preventDefault(); 56 last.focus(); 57 } else if (!event.shiftKey && document.activeElement === last) { 58 event.preventDefault(); 59 first.focus(); 60 } 61 } 62 } 63 64 function open(triggerElement) { 65 lastFocusedElement = document.activeElement; 66 67 // Inhalt anpassen, bevor das Modal sichtbar wird 68 if (typeof options.onOpen === 'function') { 69 options.onOpen(triggerElement); 70 } 71 72 overlay.hidden = false; 73 document.body.style.overflow = 'hidden'; // Hintergrund-Scroll verhindern 74 75 // Fokus in den Dialog setzen 76 var focusable = getFocusableElements(); 77 if (focusable.length) { 78 focusable[0].focus(); 79 } else { 80 dialog.setAttribute('tabindex', '-1'); 81 dialog.focus(); 82 } 83 84 document.addEventListener('keydown', onKeydown, true); 85 } 86 87 function close(e) { 88 if (e && e.preventDefault) { 89 e.preventDefault(); 90 } 91 92 overlay.hidden = true; 93 document.body.style.overflow = ''; 94 95 document.removeEventListener('keydown', onKeydown, true); 96 97 // Fokus zurück zum auslösenden Element (wichtig für Tastatur-/Screenreader-Nutzer) 98 if (lastFocusedElement) { 99 lastFocusedElement.focus(); 100 } 101 } 102 103 // Klick auf Overlay (auÃerhalb der Dialog-Box) schlieÃt das Popup 104 overlay.addEventListener('click', function (event) { 105 if (event.target === overlay) { 106 close(); 107 } 108 }); 109 110 // SchlieÃen-Buttons 111 (options.closeIds || []).forEach(function (id) { 112 var btn = document.getElementById(id); 113 if (btn) { 114 btn.addEventListener('click', close); 115 } 116 }); 117 118 return { open: open, close: close }; 119 } 120 121 /* ------------------------------------------------------------------ 122 * Gewährleistungslabel 123 * ------------------------------------------------------------------ */ 124 var warrantyModal = createModal({ 125 overlayId: 'euWarrantyOverlay', 126 dialogId: 'euWarrantyDialog', 127 closeIds: ['euWarrantyClose'] 128 }); 129 130 if (warrantyModal) { 131 var garanTriggers = document.querySelectorAll('[data-warranty-modal]'); 132 Array.prototype.forEach.call(garanTriggers, function (btn) { 133 btn.addEventListener('click', function (e) { 134 e.preventDefault(); 135 e.stopPropagation(); 136 warrantyModal.open(btn); 137 }); 138 });
139 } 140 141 /* ------------------------------------------------------------------ 142 * GARAN 143 * ------------------------------------------------------------------ */ 144 var garanModal = createModal({ 145 overlayId: 'garanOverlay', 146 dialogId: 'garanDialog', 147 closeIds: ['garanClose'], 148 onOpen: function (trigger) { 149 var data = trigger ? trigger.dataset : {}; 150 document.getElementById('garanManufacturer').textContent = data.manufacturer; 151 document.getElementById('garanMpn').textContent = data.mpn; 152 document.getElementById('garanYear').textContent = String(data.year).padStart(2, '0'); 153 } 154 }); 155 156 if (garanModal) { 157 var garanTriggers = document.querySelectorAll('[data-garan-modal]'); 158 Array.prototype.forEach.call(garanTriggers, function (btn) { 159 btn.addEventListener('click', function (e) { 160 e.preventDefault(); 161 e.stopPropagation(); 162 garanModal.open(btn); 163 }); 164 }); 165 } 166})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.