1var $ = jQuery; 2 3jQuery(function($){ 4 init_page(); 5}); 6 7function init_page(){ 8 // main navigation 9 var $navigation = $('#nav-main'); 10 $navigation.on('mouseenter', 'li', function() { 11 var $this = $(this), 12 $subMenu = $this.children('ul'); 13 if($subMenu.length){ // submenu exists 14 if($(this).hasClass('menu-level-1')){ 15 $subMenu.css("top", $(this).css("height")); 16 } 17 $subMenu.css('display', 'block'); 18 var $offset=$this.offset(); 19 var $width=$this.width(); 20 var $subMenuWidth=$subMenu.width(); 21 var $containerWidth=$( window ).width(); 22 var $offsetX=0; 23 // submenu verschieben wenn es über den Rand gehen würde 24 if(!$(this).hasClass('menu-level-1') && ($offset.left+$width+$subMenuWidth) >= $containerWidth){ 25 $offsetX=-$width; 26 $subMenu.css("left", $offsetX+'px'); 27 } 28 // 1.-level unter Hauptnavi verschieben 29 else if($(this).hasClass('menu-level-1') && ($offset.left+$subMenuWidth) >= $containerWidth){ 30 $offsetX-=$offset.left+$subMenuWidth-$containerWidth; 31 $subMenu.css("left", $offsetX+'px'); 32 } 33 // Standartverschiebung 34 else if(!$(this).hasClass('menu-level-1')){ 35 $offsetX=$width; 36 $subMenu.css("left", $offsetX+'px'); 37 } 38 } 39 }).on('mouseleave', 'li', function() { 40 $(this).children('ul').css('display', 'none'); 41 }); 42 43 //init mobile nav menu 44 var mobile_menu_ul=$("#nav-main > ul").clone(); 45 $("#nav-mobile").append(mobile_menu_ul); 46 //init mobile style helper 47 var style_helper=$("#header .style-helper-container").clone(); 48 $("#style-helper-mobile").append(style_helper); 49 50 51 //mobile menu toggle submenus 52 $(".nav-mobile-toggle-submenu").click(function(e) { 53 e.preventDefault(); 54 if($(this).hasClass("fa-plus")){ 55 $(this).removeClass("fa-plus").addClass("fa-minus"); 56 } 57 else{ 58 $(this).removeClass("fa-minus").addClass("fa-plus"); 59 } 60 var parent = $(this).parent().parent(); 61 var submenu = parent.find("ul:first"); 62 submenu.slideToggle("fast"); 63 }); 64 65 $('[data-toggle="tooltip"]').tooltip(); 66 $('[data-toggle="popover"]').popover(); 67 68 //search form 69 $('#search-form-opener').click(function() { 70 $('#search-form').slideToggle("fast"); 71 }); 72 73 //itemfilter 74 $(".itemfilter").click(function(e){ 75 e.preventDefault(); 76 $(".itemfilter").removeClass("active"); 77 $(this).addClass("active"); 78 $(".itemfilter-item").stop().fadeOut(0) 79 var selector = $(this).data('filter'); 80 if(selector=="*"){ 81 $(".itemfilter-item").stop().fadeIn(750); 82 } 83 else{ 84 $(".itemfilter-items "+selector).stop().fadeIn(750); 85 } 86 }); 87 88 //autocomplete 89 $(".search-input").keyup(function() { 90 var inputStr=$(this).val(); 91 var inputHeight=$(this).css('height'); 92 if(inputStr.length >= 3){ 93 var formElem=$(this).closest("form"); 94 var url=formElem.attr("action"); 95 var outputElem=formElem.find(".search-suggest"); 96 var outputHtml=''; 97 $.getJSON( url, { s: inputStr, mode: 'search-suggest' }) 98 .done(function( data ) { 99 $.each( data, function( i, item ) { 100 outputHtml+='<a class="search-suggest-item" href="'+item.url+'">'; 101 outputHtml+='<strong class="d-block">'+item.title; 102 // Badge hinzufügen, wenn post_type_label vorhanden ist 103 if(item.post_type_label) { 104 outputHtml+=' <span class="badge rounded-pill text-bg-light ms-1">'+item.post_type_label+'</span>'; 105 } 106 outputHtml+='</strong>'; 107 outputHtml+='<span class="color-black">'+item.description+'</span>'; 108 outputHtml+='</a>'; 109 }); 110 outputElem.css("top", inputHeight).html(outputHtml); 111 outputElem.show(); 112 }) 113 .fail(function() { 114 console.error('Autocomplete request failed'); 115 }); 116 } 117 }); 118 //autocomplete ausblenden wenn Klick auÃerhalb der Ergebisliste 119 $(document).mouseup(function(e) { 120 var container = $(".search-suggest"); 121 if (!container.is(e.target) && container.has(e.target).length === 0){ 122 container.hide(); 123 } 124 }); 125 126 // Scroll To Top Button 127 var back_to_top_button = ['<div class="btn-scroll-top"><i class="fa-sharp fa-regular fa-chevron-up"></i></div>'].join(""); 128 $("body").append(back_to_top_button); 129 $(".btn-scroll-top").hide(); 130 // Funktion für das Scroll-Verhalten 131 $(function () { 132 $(window).scroll(function () { 133 if ($(this).scrollTop() > 800) { // Wenn 800 Pixel gescrolled wurde 134 $('.btn-scroll-top').fadeIn(); 135 } else { 136 $('.btn-scroll-top').fadeOut(); 137 } 138 }); 139 $('.btn-scroll-top').click(function () { 140 $('body,html').animate({ 141 scrollTop: 0 142 }, 250); 143 return false;
144 }); 145 }); 146 147 //email_deobfuscate 148 init_email_deobfuscate(); 149 //intersection_observer => anim-inview 150 init_intersection_observer(); 151}; 152 153/* fancybox */ 154Fancybox.bind("[data-fancybox]", { 155 // Your custom options 156}); 157Fancybox.bind("[data-fancybox-ajax]", { 158 ajax: { 159 settings: { 160 dataType: 'ajax' // Sicherstellen, dass HTML geladen wird 161 } 162 }, 163 on: { 164 "*": (fancyboxRef, eventName) => { 165 if(eventName == "Carousel.contentReady"){ 166 init_email_deobfuscate(); 167 } 168 }, 169 }, 170}); 171 172// email_deobfuscate 173function init_email_deobfuscate(){ 174 const links = document.querySelectorAll(".obfuscated-email"); 175 links.forEach(el => { 176 const href = el.getAttribute("data-href"); 177 const text = el.getAttribute("data-text"); 178 el.setAttribute("href", decodeEntities(href)); 179 el.innerHTML = decodeEntities(text); 180 el.classList.remove('obfuscated-email'); 181 el.classList.add('obfuscated-email-processed'); 182 }); 183} 184function decodeEntities(str) { 185 const textarea = document.createElement('textarea'); 186 textarea.innerHTML = str; 187 return textarea.value; 188} 189 190// slider-default init (Standartverhalten) 191function init_sliders_default( $block ) { 192 const $containers = $block.find('.slider-default'); 193 if (!$containers.length) return; 194 $containers.each(function (index, element) { 195 const $container = $(element); 196 const swiper = new Swiper($container.get(0), { 197 direction: 'horizontal', 198 loop: false, 199 slidesPerView: 1, 200 spaceBetween: 20, 201 pagination: { 202 el: $container.find('.swiper-pagination').get(0), 203 clickable: true, 204 }, 205 navigation: { 206 nextEl: $container.find('.swiper-button-next').get(0), 207 prevEl: $container.find('.swiper-button-prev').get(0) 208 }, 209 }); 210 }); 211} 212 213function getPos(el) { 214 var rect=el.getBoundingClientRect(); 215 return {x:rect.left,y:rect.top}; 216} 217 218window.addEventListener('scroll', function(e) { 219 if (this.lastScroll > this.scrollY) { 220 $("#header").removeClass("header-hide"); 221 } else { 222 if (this.scrollY > 200) { 223 $("#header").addClass("header-hide"); 224 } 225 } 226 this.lastScroll = this.scrollY; 227}); 228 229/* header height wird für main padding-top benötigt */ 230function updateHeaderOffset() { 231 const header = document.querySelector('header'); 232 if (!header) return; 233 234 const offset = header.offsetHeight + 'px'; 235 document.documentElement.style.setProperty('--header-offset', offset); 236} 237updateHeaderOffset(); // beim Laden 238window.addEventListener('resize', updateHeaderOffset); // bei Resize / Orientation 239 240//IntersectionObserver fügt Elmenten der Klasse .anim die Klasse .anim-inview hinzu 241function init_intersection_observer() { 242 const items = document.querySelectorAll('.anim'); 243 // Erstelle den Intersection Observer 244 const observer = new IntersectionObserver((entries, observer) => { 245 entries.forEach(entry => { 246 if (entry.isIntersecting) { 247 // Füge die Klasse .inview hinzu, wenn das Element im Viewport ist 248 entry.target.classList.add('anim-inview'); 249 // Beende die Beobachtung dieses Elements, da die Klasse nur einmal hinzugefügt werden muss 250 observer.unobserve(entry.target); 251 } 252 }); 253 }, { 254 root: null, // Viewport als Root (Standard) 255 rootMargin: '0px', // Kein zusätzlicher Rand 256 threshold: 0.1 // 10% des Elements müssen sichtbar sein, um die Klasse hinzuzufügen 257 }); 258 // Beobachte jedes Element 259 items.forEach(tile => observer.observe(tile)); 260} 261 262 263/* lazy loading observer => für loading="lazy" nativ */ 264document.addEventListener('DOMContentLoaded', function() { 265 // Selektiere alle Bilder mit loading="lazy" 266 const lazyImages = document.querySelectorAll('img[loading="lazy"]'); 267 // Intersection Observer, um zu erkennen, wann Bilder sichtbar werden 268 const observer = new IntersectionObserver((entries, observer) => { 269 entries.forEach(entry => { 270 if (entry.isIntersecting) { 271 const img = entry.target; 272 if (img.complete && img.naturalWidth !== 0) { 273 // Bild ist bereits geladen (z. B. aus Cache) 274 img.classList.add('loaded'); 275 } else { 276 // Warte auf das load-Event 277 img.addEventListener('load', () => { 278 img.classList.add('loaded'); 279 }); 280 } 281 // Entferne den Observer, um die Beobachtung zu stoppen 282 observer.unobserve(img); 283 } 284 }); 285 }, { 286 threshold: 0.1 // Lade bei 10% Sichtbarkeit 287 }); 288 // Beobachte alle Lazy-Loading-Bilder
289 lazyImages.forEach(img => observer.observe(img)); 290}); 291
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.