1// Banner Component JavaScript 2// Handles close functionality and optional features 3 4document.addEventListener('DOMContentLoaded', function() { 5 6 const TRUST_ROTATION_INTERVAL_MS = 2800; 7 const TRUST_MOBILE_MEDIA_QUERY = '(max-width: 767px)'; 8 9 const initMobileTrustIconRotation = () => { 10 const trustBanners = document.querySelectorAll('.banner--trust'); 11 12 trustBanners.forEach((banner) => { 13 const trustItems = Array.from(banner.children).filter((item) => item.tagName === 'DIV' || item.tagName === 'A'); 14 15 if (trustItems.length < 2) { 16 return; 17 } 18 19 const mediaQuery = window.matchMedia(TRUST_MOBILE_MEDIA_QUERY); 20 let currentIndex = 0; 21 let rotationTimer = null; 22 23 const setActiveItem = (index) => { 24 trustItems.forEach((item, itemIndex) => { 25 const isActive = itemIndex === index; 26 item.classList.toggle('is-visible', isActive); 27 item.setAttribute('aria-hidden', isActive ? 'false' : 'true'); 28 29 if (item.tagName === 'A') { 30 if (isActive) { 31 if (item.dataset.originalTabindex) { 32 item.setAttribute('tabindex', item.dataset.originalTabindex); 33 delete item.dataset.originalTabindex; 34 } else { 35 item.removeAttribute('tabindex'); 36 } 37 } else { 38 if (item.hasAttribute('tabindex')) { 39 item.dataset.originalTabindex = item.getAttribute('tabindex') || ''; 40 } 41 item.setAttribute('tabindex', '-1'); 42 } 43 } 44 }); 45 }; 46 47 const startRotation = () => { 48 if (rotationTimer) { 49 return; 50 } 51 52 banner.classList.add('banner--trust-rotating');
53 setActiveItem(currentIndex); 54 55 rotationTimer = window.setInterval(() => { 56 currentIndex = (currentIndex + 1) % trustItems.length; 57 setActiveItem(currentIndex); 58 }, TRUST_ROTATION_INTERVAL_MS); 59 }; 60 61 const stopRotation = () => { 62 if (rotationTimer) { 63 window.clearInterval(rotationTimer); 64 rotationTimer = null; 65 } 66 67 banner.classList.remove('banner--trust-rotating'); 68 trustItems.forEach((item) => { 69 item.classList.remove('is-visible'); 70 item.removeAttribute('aria-hidden'); 71 72 if (item.tagName === 'A') { 73 if (item.dataset.originalTabindex) { 74 item.setAttribute('tabindex', item.dataset.originalTabindex); 75 delete item.dataset.originalTabindex; 76 } else { 77 item.removeAttribute('tabindex'); 78 } 79 } 80 }); 81 }; 82 83 const handleViewportChange = () => { 84 if (mediaQuery.matches) { 85 startRotation(); 86 } else { 87 stopRotation(); 88 } 89 }; 90 91 handleViewportChange(); 92 93 if (typeof mediaQuery.addEventListener === 'function') { 94 mediaQuery.addEventListener('change', handleViewportChange); 95 } else { 96 mediaQuery.addListener(handleViewportChange); 97 } 98 }); 99 }; 100 101 // Banner schlieÃen 102 const closeBanners = () => { 103 document.querySelectorAll('.banner__close').forEach(button => { 104 button.addEventListener('click', function() { 105 const banner = this.closest('.banner'); 106 107 // Fade-out Animation 108 banner.style.transition = 'opacity 0.3s ease, transform 0.3s ease'; 109 banner.style.opacity = '0'; 110 banner.style.transform = 'translateY(-10px)'; 111 112 setTimeout(() => { 113 banner.setAttribute('aria-hidden', 'true'); 114 banner.style.display = 'none'; 115 116 // Optional: Banner-ID in localStorage speichern 117 const bannerId = banner.getAttribute('data-banner-id'); 118 if (bannerId) { 119 localStorage.setItem('banner_closed_' + bannerId, 'true'); 120 } 121 }, 300); 122 }); 123 }); 124 }; 125 126 // Geschlossene Banner ausblenden (basierend auf localStorage) 127 const hideClosedBanners = () => { 128 document.querySelectorAll('.banner[data-banner-id]').forEach(banner => { 129 const bannerId = banner.getAttribute('data-banner-id'); 130 const isClosed = localStorage.getItem('banner_closed_' + bannerId); 131 132 if (isClosed === 'true') { 133 banner.style.display = 'none'; 134 banner.setAttribute('aria-hidden', 'true'); 135 } 136 }); 137 }; 138 139 // Initialisieren 140 closeBanners(); 141 hideClosedBanners(); 142 initMobileTrustIconRotation(); 143 144});
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.