1(function () { 2 var isLoggedIn = document.body.classList.contains("bodyLoggedIn"); 3 var isEditMode = document.body.classList.contains("editMode"); 4 5 var root = document.documentElement; 6 var scrollToTopElements = document.querySelectorAll("[data-scrolltotop]"); 7 8 // SITE LOAD 9 document.addEventListener("DOMContentLoaded", function () { 10 // if site is already scrolled on page load, add class 11 if (window.scrollY >= 1) { 12 scrollToTopElements.forEach((elem) => { 13 elem.classList.add("scrolled"); 14 }); 15 } 16 }); 17 18 // SCROLL 19 window.addEventListener("scroll", function () { 20 if (window.scrollY >= 1) { 21 scrollToTopElements.forEach((elem) => { 22 elem.classList.add("scrolled"); 23 }); 24 } else { 25 scrollToTopElements.forEach((elem) => { 26 elem.classList.remove("scrolled"); 27 }); 28 } 29 }); 30 31 // ADD WINDOW HEIGHT VARIABLE 32 var windowHeightEvents = ["load", "resize", "orientationchange"]; 33 windowHeightEvents.forEach((event) => { 34 window.addEventListener(event, function (e) { 35 // window.innerWidth returns it including the scrollbar 36 root.style.setProperty("--window-width", getComputedStyle(root).width); 37 root.style.setProperty("--window-height", window.innerHeight + "px"); 38 }); 39 }); 40 41 // ADD SHOW ICON TO EVERY ACTIVE/CURRENT MENU ITEM 42 var activeCurrentNavItems = document.querySelectorAll(".nav-item.l0.active, .nav-item.l0.current"); 43 activeCurrentNavItems.forEach((elem) => { 44 elem.classList.add("show"); 45 }); 46 47 // CLICK EVENT ON SCROLL TO TOP BUTTON 48 scrollToTopElements.forEach((elem) => { 49 elem.addEventListener("click", function () { 50 scrollToTop(); 51 }); 52 }); 53 54 // RESPONSIVE TABLES 55 var tableElems = document.querySelectorAll("section table"); 56 function detectScrollbar(elem) { 57 const container = elem.closest(".container") || elem.parentElement; 58 const styles = window.getComputedStyle(container); 59 const totalWidth = container.clientWidth; 60 const paddingLeft = parseFloat(styles.paddingLeft); 61 const paddingRight = parseFloat(styles.paddingRight); 62 const containerWidth = totalWidth - paddingLeft - paddingRight; 63 64 // offsetWidth ist gerundet, die Container-Breite bei Prozent-/vw-Padding nicht (338 > 337.5) -> 1px Toleranz 65 return elem.getBoundingClientRect().width - containerWidth > 1; 66 }
67 tableElems.forEach((elem) => { 68 function handleScrollbar(elem) { 69 var isSmaller = detectScrollbar(elem); 70 if (isSmaller) { 71 wrapper.classList.add("overflow"); 72 wrapper.addEventListener("scroll", function (e) { 73 var pos = wrapper.scrollLeft; 74 pos > 0 ? wrapper.classList.add("scrolled") : wrapper.classList.remove("scrolled"); 75 }); 76 } else { 77 wrapper.classList.remove("overflow"); 78 wrapper.classList.remove("scrolled"); 79 } 80 } 81 82 // create wrapper elem 83 var wrapper = document.createElement("div"); 84 wrapper.classList.add("table-responsive"); 85 86 // move table inside wrapper elem 87 elem.parentNode.insertBefore(wrapper, elem); 88 wrapper.appendChild(elem); 89 90 // handleScrollbar 91 handleScrollbar(elem); 92 93 // Webfonts aendern die Tabellenbreite nach dem ersten Messen -> erneut pruefen 94 if (document.fonts) { 95 document.fonts.ready.then(function () { 96 handleScrollbar(elem); 97 }); 98 } 99 100 window.addEventListener("resize", function (e) { 101 handleScrollbar(elem); 102 }); 103 }); 104 105 // CALL KLARO WINDOW FROM FOOTER MENU 106 var footers = document.querySelectorAll("ul.footer-nav li a"); 107 footers.forEach(function (item) { 108 if (item.innerHTML == "Cookies" || item.innerText == "Cookies") { 109 item.addEventListener("click", function (event) { 110 event.preventDefault(); 111 // force klaro window 112 return klaro.show(undefined, true); 113 }); 114 } 115 }); 116})(); 117 118document.addEventListener('DOMContentLoaded', () => { 119 // INIT TOOLTIPS 120 const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); 121 const tooltipList = [...tooltipTriggerList].map((tooltipTriggerEl) => new bootstrap.Tooltip(tooltipTriggerEl)); 122 123 // INIT POPOVERS 124 const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]'); 125 const popoverList = [...popoverTriggerList].map((popoverTriggerEl) => new bootstrap.Popover(popoverTriggerEl)); 126}); 127 128// SCROLL-TO-TOP FUNCTION 129function scrollToTop() { 130 window.scroll({ 131 top: 0, 132 left: 0, 133 behavior: 'smooth', 134 }); 135} 136 137document.addEventListener('DOMContentLoaded', () => { 138 const delay = 200; 139 const queue = []; 140 const elements = document.querySelectorAll('.fade-in-left, .fade-in-right, .fade-in-top, .fade-in-bottom'); 141 let isProcessing = false; 142 143 const observer = new IntersectionObserver( 144 (entries) => { 145 entries.forEach((entry) => { 146 if (entry.isIntersecting) { 147 queue.push(entry.target); 148 observer.unobserve(entry.target); // only trigger once 149 150 processQueue(); 151 } 152 }); 153 }, 154 { 155 threshold: 0.2, 156 } 157 ); 158 const processQueue = () => { 159 if (isProcessing) return; 160 if (queue.length === 0) return; 161 162 isProcessing = true; 163 164 const element = queue.shift(); 165 166 element.classList.add('visible'); 167 168 setTimeout(() => { 169 isProcessing = false; 170 processQueue(); 171 }, delay); 172 }; 173 174 for (const element of elements) { 175 observer.observe(element); 176 } 177 178 // Section-Reveals (Setting "Einblende-Effekt") brauchen eine eigene Schwelle: eine Section 179 // kann hoeher als der Viewport sein und dann nie 20 % Sichtbarkeit erreichen. 180 // Im Backend-Editiermodus bleibt alles sichtbar - der Redakteur soll die Seite sehen, 181 // nicht erst hinscrollen muessen. 182 const revealElements = document.body.classList.contains('fw-edit-mode') 183 ? [] 184 : document.querySelectorAll('[class*="pel-reveal-"]'); 185 const revealObserver = new IntersectionObserver( 186 (entries) => { 187 entries.forEach((entry) => { 188 if (entry.isIntersecting) { 189 queue.push(entry.target); 190 revealObserver.unobserve(entry.target); 191 192 processQueue(); 193 } 194 }); 195 }, 196 { 197 rootMargin: '0px 0px -10% 0px', 198 } 199 ); 200 201 for (const element of revealElements) { 202 // Startzustand erst per JS setzen - ohne JS bleibt die Section sichtbar statt auf opacity:0 203 element.classList.add('reveal-prep'); 204 revealObserver.observe(element); 205 } 206}); 207 208// MASKOTTCHEN â Spruchwechsel bei Klick. No-op, solange kein Maskottchen im DOM ist. 209document.addEventListener('DOMContentLoaded', () => { 210 const mascot = document.querySelector('[data-mascot]'); 211 if (!mascot) return; 212 213 const bubble = mascot.querySelector('[data-mascot-bubble]'); 214 const trigger = mascot.querySelector('.mascot-trigger'); 215 const sayings = [...mascot.querySelectorAll('[data-mascot-sayings] li')].map((item) => item.textContent); 216 if (!bubble || !trigger || sayings.length === 0) return; 217 218 // Die Blase zeigt beim Laden bereits Spruch 0 (serverseitig gerendert). 219 let currentIndex = 0; 220 let hideTimeout; 221 222 trigger.addEventListener('click', () => { 223 let nextIndex = currentIndex; 224 while (nextIndex === currentIndex && sayings.length > 1) { 225 nextIndex = Math.floor(Math.random() * sayings.length); 226 } 227 228 currentIndex = nextIndex; 229 bubble.textContent = sayings[nextIndex]; 230 mascot.classList.add('speaking'); 231 232 clearTimeout(hideTimeout); 233 hideTimeout = setTimeout(() => mascot.classList.remove('speaking'), 5000); 234 }); 235});
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.