PageSourceSearch

https://staudeverlag.de/wp-content/themes/dhz/assets/js/main.js?ver=1.0.2

js staudeverlag.de collected 2026-09-28 08:12:06 UTC 19,084 bytes, 618 lines download raw bytes

1(function ($) {
2  function Accordions(parent) {
3    const accordionItemsClassname = 'accordion__item';
4    const accordionItemsContentClassname = 'accordion__item__content';
5    const accordionItemsHeaderButtonClassname = 'accordion__item__header__button';
6
7    const accordionItems = parent.getElementsByClassName(accordionItemsClassname);
8
9    function init() {
10      setAccordionHeights();
11      attachClickEvents();
12
13      document.addEventListener('resize', function () {
14        setAccordionHeights();
15      });
16    }
17
18    function setAccordionItemHeight(accordionItem) {
19      const accordionItemContent = accordionItem.getElementsByClassName(accordionItemsContentClassname);
20      if (accordionItemContent && accordionItemContent.length) {
21        const accordionItemHeight = accordionItemContent[0].scrollHeight;
22        accordionItemContent[0].setAttribute('data-height', accordionItemHeight);
23        accordionItemContent[0].style.height = '0px';
24      }
25    }
26
27    function setAccordionHeights() {
28      // calculate height for each tab
29      for (let i = 0; i < accordionItems.length; i++) {
30        const accordionItem = accordionItems[i];
31        setAccordionItemHeight(accordionItem);
32      }
33    }
34
35    function attachClickEvents() {
36      for (let i = 0; i < accordionItems.length; i++) {
37        const accordionItem = accordionItems[i];
38        attachClickEvent(accordionItem);
39      }
40    }
41
42    function attachClickEvent(accordionItem) {
43      const togglers = accordionItem.getElementsByClassName(accordionItemsHeaderButtonClassname);
44
45      if (togglers) {
46        for (let i = 0; i < togglers.length; i++) {
47          const togler = togglers[i];
48
49          togler.addEventListener('click', function () {
50            updateActiveAccordion(accordionItem);
51          });
52
53        }
54      }
55    }
56
57    function updateActiveAccordion(activeTabItem) {
58      const activeAccordionItemContent = activeTabItem.getElementsByClassName(accordionItemsContentClassname)[0];
59      for (let i = 0; i < accordionItems.length; i++) {
60        const accordionItem = accordionItems[i];
61        const accordionItemContent = accordionItem.getElementsByClassName(accordionItemsContentClassname)[0];
62        const accordionItemTogglerBtn = accordionItem.getElementsByClassName(accordionItemsHeaderButtonClassname)[0];
63        if (accordionItemContent) {
64          if (accordionItemContent !== activeAccordionItemContent) {
65            accordionItemContent.style.height = 0;
66            accordionItemTogglerBtn.classList.remove('accordion__item__header__button--active');
67            accordionItemContent.classList.remove('accordion__item__content--active');
68            accordionItem.classList.remove('accordion__item--active');
69          } else {
70            const accordionItemHeight = accordionItemContent.style.height.replace('px', '');
71            const closed = accordionItemHeight === "0";
72            if (closed) {
73              accordionItemContent.style.height = accordionItemContent.getAttribute('data-height') + 'px';
74              accordionItemTogglerBtn.classList.add('accordion__item__header__button--active');
75              accordionItemContent.classList.add('accordion__item__content--active');
76              accordionItem.classList.add('accordion__item--active');
77            } else {
78              accordionItemContent.style.height = 0;
79              accordionItemTogglerBtn.classList.remove('accordion__item__header__button--active');
80              accordionItemContent.classList.remove('accordion__item__content--active');
81              accordionItem.classList.remove('accordion__item--active');
82            }
83          }
84        }
85      }
86    }
87
88    init();
89
90  }
91
92  function Tabs(options) {
93    const tabBtns = options.element.querySelectorAll('[data-tab-btn]');
94    const activeTabBtnClass = options.activeTabBtnClass;
95    const activeTabContentClass = options.activeTabContentClass;
96
97    let activeTabBtn = tabBtns[0];
98    let activeTabContent = document.querySelectorAll('[data-tab-content="' + activeTabBtn.dataset.tabBtn + '"]')[0];
99
100    activeTabBtn.classList.add(activeTabBtnClass);
101    activeTabContent.classList.add(activeTabContentClass);
102
103    if (tabBtns) {
104      for (let i = 0; i < tabBtns.length; i++) {
105        const tabBtn = tabBtns[i];
106        const tabSelector = tabBtn.dataset.tabBtn;
107        
108        tabBtn.addEventListener('click', function(e) {
109          const selectedTabContent = document.querySelectorAll('[data-tab-content="' + tabSelector + '"]');
110          this.classList.add(activeTabBtnClass);
111
112          if (tabBtn != activeTabBtn) {
113            if (activeTabBtn) {
114              activeTabBtn.classList.remove(activeTabBtnClass);
115            }
116            activeTabBtn = this;
117          }
118
119          if (selectedTabContent && selectedTabContent[0]) {
120            selectedTabContent[0].classList.add(activeTabContentClass);
121
122            if (selectedTabContent[0] != activeTabContent) {
123              if (activeTabContent) {
124                activeTabContent.classList.remove(activeTabContentClass)
125              }
126              activeTabContent = selectedTabContent[0];
127            }
128          }
129        });
130      }
131    }
132  }
133
134  function Toggle(options) {
135    const toggleBtnElm = options.element;
136    const toggleContentSelector = toggleBtnElm.dataset.toggleBtn;
137    const toggleContentElm = document.querySelector('[data-toggle-content="' + toggleContentSelector + '"]');
138
139    const activeToggleBtnClass = toggleBtnElm.dataset.toggleBtnActiveClass;
140    const activeToggleContentClass = toggleContentElm && toggleContentElm.dataset ? toggleContentElm.dataset.toggleContentActiveClass : "";
141
142    function toggleContent() {
143      if (activeToggleBtnClass) {
144        toggleBtnElm.classList.toggle(activeToggleBtnClass);
145      }
146      toggleContentElm.classList.toggle(activeToggleContentClass);
147    }
148
149    if (toggleBtnElm && toggleContentElm) {
150      toggleBtnElm.addEventListener('click', function(e) {
151        toggleContent(toggleContentElm);
152      });
153    }
154  }
155
156  function LimitedList(list) {
157    const listElm = list;
158    const listItems = listElm.querySelectorAll('[data-limit-list-item]');
159    const visibleItems = +listElm.dataset.limitList;
160    const showAllItemsElm = listElm.querySelector('[data-list-show-all]');
161
162    if (visibleItems <= listItems.length) {
163      for (let i = visibleItems; i < listItems.length; i++) {
164        const listItem = listItems[i];
165        listItem.style.display = 'block';
166      }
167    }
168
169    if (showAllItemsElm) {
170      if (visibleItems >= listItems.length) {
171        showAllItemsElm.style.display = 'block';
172      }
173
174      showAllItemsElm.addEventListener('click', function() {
175        for (let i = visibleItems; i < listItems.length; i++) {
176          const listItem = listItems[i];
177          listItem.style.display = 'block';
178        }
179        this.style.display = 'block';
180      })
181    }
182  }
183
184  function menuSlider() {
185    var activeSlide = 1;
186    var visibleSlidesMapper = {
187      0: 2,
188      768: 3,
189      992: 4,
190      1200: 5,
191      1400: 8,
192    }
193    var visibleSlides = visibleSlidesMapper[768];
194    var menuItems = $('.fullWidthMenu ul li');
195
196    if (menuItems.length) {
197      setVisibleItems();
198    }
199  
200    function setVisibleItems() {
201      var ww = $(window).width();
202
203      for (const ss in visibleSlidesMapper) {
204        if (Object.hasOwnProperty.call(visibleSlidesMapper, ss)) {
205          if (ww > ss) {
206            visibleSlides = visibleSlidesMapper[ss];
207          }
208        }
209      }
210
211      menuItems.each(function (i) {
212        if (menuItems.length <= visibleSlides || (i >= (activeSlide - 1) * visibleSlides && i < activeSlide * visibleSlides)) {
213          $(this).show();
214        } else {
215          $(this).hide();
216        }
217      });
218    }
219
220    var menusliderBtn = document.querySelector('.category-menu-next');
221    if (menusliderBtn) {
222      document.querySelector('.category-menu-next').addEventListener('click', function(e) {
223        e.preventDefault();
224        activeSlide++;
225        if ((activeSlide - 1) * visibleSlides >= menuItems.length) {
226          activeSlide = 1;
227        }
228        setVisibleItems();
229      });
230  
231      $(window).resize(setVisibleItems);
232    }
233  }
234
235  document.addEventListener('DOMContentLoaded', function () {
236    // get all accordions
237    const allAccordions = document.getElementsByClassName('accordion');
238
239    for (let i = 0; i < allAccordions.length; i++) {
240      const accordions = allAccordions[i];
241      new Accordions(accordions);
242    }
243
244    const allTabs = document.querySelectorAll('[data-tab-group]');
245    for (let i = 0; i < allTabs.length; i++) {
246      const tabGroup = allTabs[i];
247      new Tabs({
248        element: tabGroup,
249        activeTabBtnClass: 'tabs__btns__item--active',
250        activeTabContentClass: 'tabs__content__item--active'
251      });
252    }
253
254    const allToggleBtns = document.querySelectorAll('[data-toggle-btn]');
255    for (let i = 0; i < allToggleBtns.length; i++) {
256      const toggleBtn = allToggleBtns[i];
257      new Toggle({
258        element: toggleBtn,
259        // activeToggleBtnClass: 'toggle-btn--active',
260        // activeToggleContentClass: 'toggle-content--active'
261      });
262    }
263
264    const allLimitedLists = document.querySelectorAll('[data-limit-list]');
265    for (let i = 0; i < allLimitedLists.length; i++) {
266      const limitedList = allLimitedLists[i];
267      new LimitedList(limitedList);
268    }
269
270    // init custom dropdown
271    const customDropdowns = $('[data-custom-dropdown]');
272    customDropdowns.each(function(){
273      const dropdownItem = $(this);
274      const parent = $(this).closest('.archive-filters__wrapper') && $(this).closest('.archive-filters__wrapper').length || $(this).closest('.termine-filtering__author');
275
276      const dropdownOptions = {
277        language: {
278          noResults: function() {
279            return 'keine Ergebnisse'
280          }
281        }
282      }
283
284      if (parent.length) {
285        dropdownOptions['dropdownParent'] = parent;
286      }
287
288      dropdownItem.select2(dropdownOptions);
289    });
290
291    const customDropdownsNoFilter = $('.js-custom-dropdown--no-filter');
292    customDropdownsNoFilter.each(function(){
293      const dropdownItem = $(this);
294      const parent = $(this).closest('.archive-filters__wrapper');
295
296      dropdownItem.select2({
297        minimumResultsForSearch: Infinity,
298        dropdownParent: parent,
299        language: {
300          noResults: function() {
301            return 'keine Ergebnisse'
302          }
303        }
304      });
305    });
306
307    $('[data-custom-datepicker]').MonthPicker(
308      { 
309        ShowIcon: false,
310        MonthFormat: 'mm.yy',
311        
312        i18n: {
313          year: "",
314          buttonText: "",
315          prevYear: "",
316          nextYear: "",
317          next12Years: "",
318          prev12Years: "",
319          nextLabel: "", 
320          prevLabel: "",
321          jumpYears: "Sprungjahre",
322          backTo: "Zurück ins Jahr",
323          months: ["Jan", "Feb", "Mär", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
324        }
325      }
326    );
327	  
328	  $('.termine-filtering__date [data-custom-datepicker]').MonthPicker(
329      { 
330        ShowIcon: false,
331        MonthFormat: 'mm.yy',
332        MinMonth: 0,
333        i18n: {
334          year: "",
335          buttonText: "",
336          prevYear: "",
337          nextYear: "",
338          next12Years: "",
339          prev12Years: "",
340          nextLabel: "", 
341          prevLabel: "",
342          jumpYears: "Sprungjahre",
343          backTo: "Zurück ins Jahr",
344          months: ["Jan", "Feb", "Mär", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
345        }
346      }
347    );
348
349    // init custom select for form
350    const formDropdowns = $('[data-gravity-form] select');
351    formDropdowns.each(function(){
352      $(this).select2({
353        minimumResultsForSearch: Infinity,
354        language: {
355          noResults: function() {
356            return 'keine Ergebnisse'
357          }
358        }
359      });
360    });
361
362    // filters toggler
363    $('[data-filters-toggler]').on('click', function() {
364      $('.archive-filters__toggler__label').toggleClass('archive-filters__toggler__label--hidden');
365      $('.archive-filters + form').toggle();
366    });
367
368    // toggle sharing
369    $('[data-sharing]').on('click', function(){
370      $(this).find('div').toggle();
371    });
372
373    $(document).ready(function(){
374      $('[data-slick]').slick();
375    });
376
377    menuSlider();
378
379    function slideToContent(btn, location, space) {
380      if (!location) return;
381
382      btn.addEventListener('click', () => {
383        $('html, body').animate({
384          scrollTop: $(location).offset().top - space
385        }, 200);
386      });
387    }
388
389    function initSlideToContent() {
390      const btns = document.querySelectorAll('[data-slide-to]');
391
392      if (!btns) return;
393
394      btns.forEach(btn => {
395        const key = btn.dataset.slideTo;
396        const location = document.querySelector('[data-slide-in="'+ key +'"]');
397        const topSpace = document.querySelector('header')?.scrollHeight;
398        const breadcrumbs = document.querySelector('.breadcrumbs')?.scrollHeight;
399        slideToContent(btn, location, (topSpace ?? 0) + (breadcrumbs ?? 0));
400      });
401    }
402
403    initSlideToContent();
404
405  });
406
407  $(window).load(function() {
408    $('.author-box__image__src, .event-slider__slides__item__image img').each(function() {
409      if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth === 0) {
410        this.src = $('#js-var-no-photo-image-src').text();
411      }
412    });
413  });
414
415  // search slider
416  ($(function () {
417    var slickData = {
418      infinite: true,
419      slidesToShow: 4,
420      slidesToScroll: 1,
421      responsive: [
422        {
423          breakpoint: 1480,
424          settings: {
425            slidesToShow: 3
426          },
427        },
428        {
429          breakpoint: 1024,
430          settings: {
431            slidesToShow: 2
432          },
433        },
434        {
435          breakpoint: 768,
436          settings: {
437            slidesToShow: 2
438          },
439        },
440        {
441          breakpoint: 670,
442          settings: {
443            slidesToShow: 1
444          },
445        },
446      ]
447    };
448
449    var $academySlider = $('.search-slider:not(.no-slider) .academy-slider');
450    var $shopSlider = $('.search-slider:not(.no-slider) .shop-slider');
451    slickData["prevArrow"] = ".academy-slider-arrow-prev";
452    slickData["nextArrow"] = ".academy-slider-arrow-next";
453    $academySlider.slick(slickData);
454
455    slickData["prevArrow"] = ".shop-slider-arrow-prev";
456    slickData["nextArrow"] = ".shop-slider-arrow-next";
457    $shopSlider.slick(slickData);
458
459  }));
460
461  $(document).on('click', '.top-menu__search__toggle, .top-menu__search__close-button', function (e) {
462    e.preventDefault();
463    $('.top-menu__search').toggleClass('active');
464  });
465
466  $(document).on('click', '.js-offcanvas-close', function (e) {
467    e.preventDefault();
468    $('.mobile-nav').toggleClass('active');
469  });
470
471  function dooIframeSetHeight() {
472    let iframe = document.getElementById('iframe-doo-termine');
473    if (iframe) {
474      iframe.height = (iframe.contentWindow.document.body.scrollHeight + 20) + "px";
475    }
476  }
477
478  /* $(document).ready(function() {
479    if ((('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))) {
480      $("body").addClass("is-touch");
481    } else {
482      $("body").addClass("no-touch");
483    }
484  }); */
485
486  setInterval(function () {
487    dooIframeSetHeight();
488  }, 500);
489
490  let lastIframeHeight = null;
491  let hasUserInteractedInsideIframe = false;
492  let lastScrollTime = 0;
493
494  function dooIframeSetHeight() {
495    const iframe = document.getElementById('iframe-doo-termine');
496
497    if (iframe && iframe.contentWindow && iframe.contentWindow.document.body) {
498      const newHeight = iframe.contentWindow.document.body.scrollHeight + 20;
499
500      if (newHeight !== lastIframeHeight) {
501        iframe.height = newHeight + "px";
502
503        // Height delta
504        const heightDifference = Math.abs(newHeight - (lastIframeHeight || 0));
505
506        // Only scroll if:
507        // 1. user interacted
508        // 2. AND height changed significantly (over 150px, e.g. form step or submit)
509        // 3. AND not scrolled recently (e.g. in last 1 sec)
510        if (
511          hasUserInteractedInsideIframe &&
512          lastIframeHeight !== null &&
513          heightDifference > 150 &&
514          Date.now() - lastScrollTime > 1000
515        ) {
516          const wrapper = document.getElementById('iframe-doo-wrapper');
517          if (wrapper) {
518            wrapper.scrollIntoView({ behavior: 'smooth', block: 'start' });
519            lastScrollTime = Date.now();
520          }
521        }
522
523        lastIframeHeight = newHeight;
524      }
525    }
526  }
527
528  function detectIframeInteraction() {
529    const iframe = document.getElementById('iframe-doo-termine');
530    if (!iframe) return;
531
532    iframe.addEventListener('load', () => {
533      try {
534        // Same-origin iframe: listen for internal clicks
535        iframe.contentWindow.document.addEventListener('click', () => {
536          hasUserInteractedInsideIframe = true;
537        });
538      } catch (e) {
539        // Cross-origin iframe: fallback
540      }
541    });
542
543    // Cross-origin fallback: use one-time focus/touchstart
544    iframe.addEventListener('focus', () => {
545      hasUserInteractedInsideIframe = true;
546    }, { once: true });
547
548    iframe.addEventListener('touchstart', () => {
549      hasUserInteractedInsideIframe = true;
550    }, { once: true });
551
552    iframe.addEventListener('mouseenter', () => {
553      hasUserInteractedInsideIframe = true;
554    }, { once: true });
555  }
556
557  document.addEventListener('DOMContentLoaded', function () {
558    detectIframeInteraction();
559  });
560
561  setInterval(dooIframeSetHeight, 500);
562
563
564
565
566document.addEventListener("DOMContentLoaded", function () {
567  if (window.innerWidth <= 768 && window.location.hash === "#LIP_Workshops") {
568    // Prevent browser’s default jump
569    window.scrollTo(0, 0);
570
571    const target = document.getElementById("LIP_Workshops");
572    const iframe = document.querySelector("#iframe-doo-termine");
573
574    if (!target || !iframe) return;
575
576    const minHeight = 400;
577    const maxWaitTime = 6000;
578    const pollInterval = 200;
579
580    let previousHeight = 0;
581    let stableCount = 0;
582    let waited = 0;
583
584    const poll = setInterval(() => {
585      const currentHeight = iframe.offsetHeight;
586
587      // Check if iframe has expanded beyond minimum threshold
588      if (currentHeight > minHeight) {
589        if (currentHeight === previousHeight) {
590          stableCount++;
591        } else {
592          stableCount = 0;
593        }
594        previousHeight = currentHeight;
595
596        // When iframe height is stable over several checks, then scroll
597        if (stableCount >= 3) {
598          clearInterval(poll);
599          setTimeout(() => {
600            const offset = 100;
601            const scrollY = target.getBoundingClientRect().top + window.scrollY - offset;
602            window.scrollTo({ top: scrollY, behavior: "smooth" });
603          }, 150);
604        }
605      }
606
607      waited += pollInterval;
608      if (waited >= maxWaitTime) {
609        clearInterval(poll);
610      }
611    }, pollInterval);
612  }
613});
614
615
616
617
618})(jQuery);

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.