PageSourceSearch

https://www.das-nest-mainz.de/js/custom.251111125507.js

js das-nest-mainz.de collected 2026-10-08 07:19:24 UTC 17,964 bytes, 628 lines download raw bytes

1/* JS for preset "Menu Hamburger" */
2(function() {
3	$(function() {
4		$('.menu-wrapper-hamburger').each(function() {
5			initMenu($(this))
6		});
7	});
8
9	// Make :active pseudo classes work on iOS
10	document.addEventListener("touchstart", function() {}, false);
11
12	var initMenu = function($menuWrapper) {
13		var $body = $('body');
14		var $menu = $('.ed-menu', $menuWrapper);
15		var $hamburgerMenu = $('.hamburger-menu', $menuWrapper);
16		var $menuLinks = $('a', $menu);
17		var $menuTrigger = $('.menu-trigger-hamburger', $menuWrapper);
18		var $banner = $('.banner').first();
19
20		var menuWrapperHeight = $menuWrapper.outerHeight();
21		var bannerHeight = $banner.length ? $banner.outerHeight() : 0;
22		var smoothScrollOffset = 20;
23		
24		toggleClassOnClick($body.add($hamburgerMenu), $menuTrigger, null, 'open open-menu-hamburger');  // Keep open on $menu for backward compatibility
25		activateSmoothScroll($menuLinks.add($('.scroll a')), smoothScrollOffset);
26		addClassOnVisibleLinkTargets($menuLinks, 'active', 2 / 3);
27		handleSticky($menuWrapper, 'sticky', $banner);
28	};
29
30	/**
31	 * Observe element's height changes and reload the initMenu() function
32	 *
33	 * @param {HTMLElement} elm Element to observe
34	 * @param {function} callback to call when elmement's height changed
35	 */
36	var observeHeightChange = function(elm, callback) {
37		if (!('ResizeObserver' in window) || elm == null) return;
38
39		var ro = new ResizeObserver(callback);
40		ro.observe(elm);
41	}
42
43	/**
44	 * Toggles class on a target when a trigger is clicked
45	 * 
46	 * @param {jQuery} $target The target to apply the CSS class to
47	 * @param {jQuery} $trigger The Trigger
48	 * @param {jQuery} $closeTrigger Optional close trigger
49	 * @param {string} cssClass CSS Class to toggle on the target
50	 */
51	var toggleClassOnClick = function($target, $trigger, $closeTrigger, cssClass) {
52
53		// Reset in case class "open" was saved accidentally
54		$target.removeClass(cssClass);
55		$trigger.removeClass(cssClass);
56
57		// Click on trigger toggles class "open"
58		$trigger.off('.toggle').on('click.toggle', function() {
59			$(this).toggleClass(cssClass);
60			$target.toggleClass(cssClass);
61		});
62
63		// Close target when link inside is clicked
64		$target.find('a').click(function() {
65			$target.removeClass(cssClass);
66			$trigger.removeClass(cssClass);
67		});
68
69		if (!$closeTrigger || !$closeTrigger.length) {
70			return;
71		}
72
73		$closeTrigger.click(function() {
74			$target.removeClass(cssClass);
75			$trigger.removeClass(cssClass);
76		});
77	};
78
79	/**
80	 * Smooth scroll to link targets
81	 * 
82	 * @param {jQuery} $scrollLinks The links
83	 * @param {jQuery} scrollOffset Offset to subtract from the scroll target position (e.g. for fixed positioned elements like a menu)
84	 */
85	var activateSmoothScroll = function($scrollLinks, scrollOffset) {
86		if (typeof scrollOffset === 'undefined') {
87			scrollOffset = 0;
88		}
89
90		var determineTarget = function($trigger, hash) {
91			if (hash == '#!next') {
92				return $trigger.closest('.ed-element').next();
93			}
94
95			return $(hash);
96		}
97
98		$scrollLinks.click(function(e) {
99			var $target = determineTarget($(this), this.hash);
100			if (!$target.length) return;
101			e.preventDefault();
102
103			viewport.scrollTo($target, 'top', 500, 0);
104
105		});
106	};
107
108	/**
109	 * We are using the fill property on an element to pass user's choices from CSS to JavaScript
110	 * 
111	 * @param {jQuery} $element
112	 */
113	var getStickyMode = function($element) {
114		var fillValue = getComputedStyle($element[0]).fill;
115
116		return fillValue === 'rgb(255, 0, 0)' ?
117			'sticky_banner' :
118			fillValue === 'rgb(0, 255, 0)' ?
119			'sticky_menu' :
120			fillValue === 'rgb(0, 0, 255)' ?
121			'sticky_instant' :
122			fillValue === 'rgb(255, 255, 255)' ?
123			'sticky_reverse' :
124			'sticky_none';
125	};
126
127	/**
128	 * Adds a class to an element when not currently visible
129	 * 
130	 * @param {jQuery} $element The element to handle stickyness for
131	 * @param {string} cssClass The actual CSS class to be applied to the element when it's above a certain scroll position
132	 * @param {jQuery} $banner A banner to reference the scroll position to
133	 */
134	var handleSticky = function($element, cssClass, $banner) {
135		var triggerPos = 0,
136			offset = 0;
137		var menuWrapperHeight = $element.outerHeight();
138		var mode;
139		var prevScroll = 0;
140		$element.removeClass(cssClass);
141		
142		var toggleSpacer = function(toggle) {
143			document.body.style.setProperty('--spacer-height', toggle ? menuWrapperHeight + 'px' : '');
144		};
145
146		var handleScroll = function() {
147			if (!$element.length || mode === 'sticky_none') return;
148
149			var isReverse = mode === 'sticky_reverse',
150				curScroll = viewport.getScrollTop();
151
152			if (triggerPos <= curScroll && (!isReverse || prevScroll > curScroll)) {
153				$element.addClass(cssClass);
154				toggleSpacer(true);
155			} else {
156				$element.removeClass(cssClass);
157				toggleSpacer(false);
158			}
159
160			prevScroll = curScroll;
161		};
162		
163		var updateOffset = function() {
164			mode = getStickyMode($element);
165			menuWrapperHeight = $element.outerHeight();
166			if (!$element.hasClass(cssClass)) {
167				offset = $element.offset().top;
168			}
169			if (mode === 'sticky_banner' && !$banner.length) {
170				mode = 'sticky_menu';
171			}
172			if (mode === 'sticky_banner') {
173				triggerPos = $banner.offset().top + ($banner.length ? $banner.outerHeight() : $element.outerHeight());
174			}
175			if (mode === 'sticky_menu' || mode === 'sticky_reverse') {
176				triggerPos = offset + $element.outerHeight();
177			}
178			if (mode === 'sticky_instant') {
179				triggerPos = offset;
180			}
181			
182			handleScroll();
183		}
184		
185		viewport.observe('resize', updateOffset);
186		viewport.observe('animation.end', updateOffset);
187		observeHeightChange($element[0], updateOffset);
188		updateOffset();
189		
190		viewport.observe('scroll', handleScroll);
191		handleScroll();
192	};
193
194	/**
195	 * Adds a class to links whose target is currently inside the viewport
196	 * 
197	 * @param {jQuery} $links Link(s) to be observed
198	 * @param {string} cssClass CSS Class to be applied
199	 * @param {float} sectionViewportRatio Ratio by which the target should be within the viewport
200	 */
201	var addClassOnVisibleLinkTargets = function($links, cssClass, sectionViewportRatio) {
202		if (typeof sectionViewportRatio === 'undefined') {
203			sectionViewportRatio = 1 / 2;
204		}
205
206		var menuTargets = [];
207		var activeLink = $links.filter('.active:not(.wv-link-elm)').eq(0);
208
209		var links = $links.filter(function() {
210			var $target = $(this.hash);
211			if (!$target.length) {
212				return false;
213			}
214
215			// Cache offset position to improve performance (update on resize)		
216			var updateOffset = function() {
217				$target.data('offset', $target.offset().top);
218			};
219
220			viewport.observe('resize', updateOffset);
221			viewport.observe('animation.end', updateOffset);
222			updateOffset();
223
224			menuTargets.push($target);
225			return true;
226		});
227
228		// No hash links found, so don't handle it at all
229		if (!links.length) {
230			return;
231		}
232
233		var checkVisibility = function() {
234			$links.removeClass('active');
235
236			// Check section position reversely
237			for (var i = menuTargets.length - 1; i >= 0; i--) {
238				var desiredScrollPosition = menuTargets[i].data('offset') - viewport.getHeight() * (1 - sectionViewportRatio);
239				if (viewport.getScrollTop() >= desiredScrollPosition && menuTargets[i][0].offsetParent !== null) {
240					links.eq(i).addClass(cssClass);
241					return;
242				}
243			}
244
245			// Fallback to originally active item
246			activeLink.addClass(cssClass);
247		};
248
249		viewport.observe('scroll', checkVisibility);
250		checkVisibility();
251	};
252})();
253/* End JS for preset "Menu Hamburger" */
254
255/* JS for preset "Menu V2" */
256(function() {
257	$(function() {
258		$('.menu-wrapper').each(function() {
259			initMenu($(this))
260		});
261	});
262
263	// Make :active pseudo classes work on iOS
264	document.addEventListener("touchstart", function() {}, false);
265
266	var initMenu = function($menuWrapper) {
267		var $body = $('body');
268		var $menu = $('.ed-menu', $menuWrapper);
269		var $menuLinks = $('a', $menu);
270		var $menuTrigger = $('.menu-trigger', $menuWrapper);
271		var $banner = $('.banner').first();
272
273		var menuWrapperHeight = $menuWrapper.outerHeight();
274		var bannerHeight = $banner.length ? $banner.outerHeight() : 0;
275		var smoothScrollOffset = 20;
276		
277		toggleClassOnClick($body.add($menu), $menuTrigger, null, 'open open-menu'); // Keep open on $menu for backward compatibility
278		activateSmoothScroll($menuLinks.add($('.scroll a')), smoothScrollOffset);
279		addClassOnVisibleLinkTargets($menuLinks, 'active', 2 / 3);
280		handleSticky($menuWrapper, 'sticky', $banner);
281	};
282
283	/**
284	 * Observe element's height changes and reload the initMenu() function
285	 *
286	 * @param {HTMLElement} elm Element to observe
287	 * @param {function} callback to call when elmement's height changed
288	 */
289	var observeHeightChange = function(elm, callback) {
290		if (!('ResizeObserver' in window) || elm == null) return;
291
292		var ro = new ResizeObserver(callback);
293		ro.observe(elm);
294	}
295
296	/**
297	 * Toggles class on a target when a trigger is clicked
298	 * 
299	 * @param {jQuery} $target The target to apply the CSS class to
300	 * @param {jQuery} $trigger The Trigger
301	 * @param {jQuery} $closeTrigger Optional close trigger
302	 * @param {string} cssClass CSS Class to toggle on the target
303	 */
304	var toggleClassOnClick = function($target, $trigger, $closeTrigger, 
304cssClass) {
305
306		// Reset in case class "open" was saved accidentally
307		$target.removeClass(cssClass);
308		$trigger.removeClass(cssClass);
309
310		// Click on trigger toggles class "open"
311		$trigger.off('.toggle').on('click.toggle', function() {
312			$(this).toggleClass(cssClass);
313			$target.toggleClass(cssClass);
314		});
315
316		// Close target when link inside is clicked
317		$target.find('a').click(function() {
318			$target.removeClass(cssClass);
319			$trigger.removeClass(cssClass);
320		});
321
322		if (!$closeTrigger || !$closeTrigger.length) {
323			return;
324		}
325
326		$closeTrigger.click(function() {
327			$target.removeClass(cssClass);
328			$trigger.removeClass(cssClass);
329		});
330	};
331
332	/**
333	 * Smooth scroll to link targets
334	 * 
335	 * @param {jQuery} $scrollLinks The links
336	 * @param {jQuery} scrollOffset Offset to subtract from the scroll target position (e.g. for fixed positioned elements like a menu)
337	 */
338	var activateSmoothScroll = function($scrollLinks, scrollOffset) {
339		if (typeof scrollOffset === 'undefined') {
340			scrollOffset = 0;
341		}
342
343		var determineTarget = function($trigger, hash) {
344			if (hash == '#!next') {
345				return $trigger.closest('.ed-element').next();
346			}
347
348			return $(hash);
349		}
350
351		$scrollLinks.click(function(e) {
352			var $target = determineTarget($(this), this.hash);
353			if (!$target.length) return;
354			e.preventDefault();
355
356			viewport.scrollTo($target, 'top', 500, 0);
357
358		});
359	};
360
361	/**
362	 * We are using the fill property on an element to pass user's choices from CSS to JavaScript
363	 * 
364	 * @param {jQuery} $element
365	 */
366	var getStickyMode = function($element) {
367		var fillValue = getComputedStyle($element[0]).fill;
368
369		return fillValue === 'rgb(255, 0, 0)' ?
370			'sticky_banner' :
371			fillValue === 'rgb(0, 255, 0)' ?
372			'sticky_menu' :
373			fillValue === 'rgb(0, 0, 255)' ?
374			'sticky_instant' :
375			fillValue === 'rgb(255, 255, 255)' ?
376			'sticky_reverse' :
377			'sticky_none';
378	};
379
380	/**
381	 * Adds a class to an element when not currently visible
382	 * 
383	 * @param {jQuery} $element The element to handle stickyness for
384	 * @param {string} cssClass The actual CSS class to be applied to the element when it's above a certain scroll position
385	 * @param {jQuery} $banner A banner to reference the scroll position to
386	 */
387	var handleSticky = function($element, cssClass, $banner) {
388		var triggerPos = 0,
389			offset = 0;
390		var menuWrapperHeight = $element.outerHeight();
391		var mode;
392		var prevScroll = 0;
393		$element.removeClass(cssClass);
394		
395		var toggleSpacer = function(toggle) {
396			document.body.style.setProperty('--spacer-height', toggle ? menuWrapperHeight + 'px' : '');
397		};
398
399		var handleScroll = function() {
400			if (!$element.length || mode === 'sticky_none') return;
401
402			var isReverse = mode === 'sticky_reverse',
403				curScroll = viewport.getScrollTop();
404
405			if (triggerPos <= curScroll && (!isReverse || prevScroll > curScroll)) {
406				$element.addClass(cssClass);
407				toggleSpacer(true);
408			} else {
409				$element.removeClass(cssClass);
410				toggleSpacer(false);
411			}
412
413			prevScroll = curScroll;
414		};
415		
416		var updateOffset = function() {
417			mode = getStickyMode($element);
418			menuWrapperHeight = $element.outerHeight();
419			if (!$element.hasClass(cssClass)) {
420				offset = $element.offset().top;
421			}
422			if (mode === 'sticky_banner' && !$banner.length) {
423				mode = 'sticky_menu';
424			}
425			if (mode === 'sticky_banner') {
426				triggerPos = $banner.offset().top + ($banner.length ? $banner.outerHeight() : $element.outerHeight());
427			}
428			if (mode === 'sticky_menu' || mode === 'sticky_reverse') {
429				triggerPos = offset + $element.outerHeight();
430			}
431			if (mode === 'sticky_instant') {
432				triggerPos = offset;
433			}
434			
435			handleScroll();
436		}
437		
438		viewport.observe('resize', updateOffset);
439		viewport.observe('animation.end', updateOffset);
440		observeHeightChange($element[0], updateOffset);
441		updateOffset();
442		
443		viewport.observe('scroll', handleScroll);
444		handleScroll();
445	};
446
447	/**
448	 * Adds a class to links whose target is currently inside the viewport
449	 * 
450	 * @param {jQuery} $links Link(s) to be observed
451	 * @param {string} cssClass CSS Class to be applied
452	 * @param {float} sectionViewportRatio Ratio by which the target should be within the viewport
453	 */
454	var addClassOnVisibleLinkTargets = function($links, cssClass, sectionViewportRatio) {
455		if (typeof sectionViewportRatio === 'undefined') {
456			sectionViewportRatio = 1 / 2;
457		}
458
459		var menuTargets = [];
460		var activeLink = $links.filter('.active:not(.wv-link-elm)').eq(0);
461
462		var links = $links.filter(function() {
463			var $target = $(this.hash);
464			if (!$target.length) {
465				return false;
466			}
467
468			// Cache offset position to improve performance (update on resize)		
469			var updateOffset = function() {
470				$target.data('offset', $target.offset().top);
471			};
472
473			viewport.observe('resize', updateOffset);
474			viewport.observe('animation.end', updateOffset);
475			updateOffset();
476
477			menuTargets.push($target);
478			return true;
479		});
480
481		// No hash links found, so don't handle it at all
482		if (!links.length) {
483			return;
484		}
485
486		var checkVisibility = function() {
487			$links.removeClass('active');
488
489			// Check section position reversely
490			for (var i = menuTargets.length - 1; i >= 0; i--) {
491				var desiredScrollPosition = menuTargets[i].data('offset') - viewport.getHeight() * (1 - sectionViewportRatio);
492				if (viewport.getScrollTop() >= desiredScrollPosition && menuTargets[i][0].offsetParent !== null) {
493					links.eq(i).addClass(cssClass);
494					return;
495				}
496			}
497
498			// Fallback to originally active item
499			activeLink.addClass(cssClass);
500		};
501
502		viewport.observe('scroll', checkVisibility);
503		checkVisibility();
504	};
505})();
506/* End JS for preset "Menu V2" */
507
508/* JS for preset "Back to top button V3" */
509(function() {
510    var initBackToTop = function() {
511        var $button = $('.back-to-top-button-icon');
512        
513    	clickToTop($button);
514    	
515    	// Show back to top only below the fold
516    	viewport.observe('scroll', function() {
517    		if (viewport.getScrollTop() > (viewport.getHeight() / 3)) {
518    			$button.addClass('show');
519    		} else {
520    			$button.removeClass('show');
521    		}
522    	});
523    };
524    
525    var clickToTop = function($trigger) {
526    	$trigger.removeClass('show');
527    
528    	$trigger.click(function(e) {
529    		e.preventDefault();
530    		viewport.scrollTo(0, 'top', 500, 0);
531    	});
532    };
533    
534    $(initBackToTop);
535})();
536/* End JS for preset "Back to top button V3" */
537
538/* JS for preset "Cookie Consent Bar V3" */
539$(function() {
540	$('#cookieClose').click(function(e) {
541		e.preventDefault();
542		createCookie('cookieConsentBar', "rejected", 0.5);
543		$('.cookie-consent-bar').hide();
544		
545		// If inside of an overlay, close it too
546		if ($('.cookie-consent-bar').closest('.mfp-content').length) {
547			$.magnificPopup.close();
548			return;
549		}
550	});
551
552	$('#acceptCookie').click(function(e) {
553		e.preventDefault();
554		createCookie('cookieConsentBar', "accepted", 0.5);
555		$('.cookie-consent-bar').hide();
556
557		if (typeof ThirdPartyScripts !== "undefined") {
558			ThirdPartyScripts.unblock();
559		}
560
561		// If inside of an overlay, close it too
562		if ($('.cookie-consent-bar').closest('.mfp-content').length) {
563			$.magnificPopup.close();
564			return;
565		}
566	});
567
568	var preview = false;
569	
570	var listener = function() {
571		if (!preview && document.body.classList.contains('preview')) {
572			console.log("entering preview");
573			preview = true;
574		} else if (preview && !document.body.classList.contains('preview')) {
575			console.log("leaving preview");
576			$('.cookie-consent-bar').show();
577			preview = false;
578		}
579		requestAnimationFrame(listener);
580	};
581	
582	requestAnimationFrame(listener);
583
584	if (document.body.classList.contains('edit') || document.body.classList.contains('preview')) {
585		return;
586	}
587
588	
589	// Cookie bar
590	if (readCookie('cookieConsentBar') == "accepted") {
591		$('.cookie-consent-bar').hide();
592		window.setTimeout(function() {
593			if (typeof ThirdPartyScripts !== "undefined") {
594				ThirdPartyScripts.unblock();
595			}
596		}, 100);
597	} else if (readCookie('cookieConsentBar') == "rejected") {
598		$('.cookie-consent-bar').hide();
599	} else {
600		$('.cookie-consent-bar').show();
601	}
602	
603	function readCookie(name) {
604		var nameEQ = name + "=";
605		var ca = document.cookie.split(';');
606		for (var i = 0; i < ca.length; i++) {
607			var c = ca[i];
608			while (c.charAt(0) == ' ') c = c.substring(1, c.length);
609			if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
610		}
611		return null;
612	}   
613    
614	function createCookie(name, value, days) {
615		if (days) {
616			var date = new Date();
617			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
618			var expires = "; expires=" + date.toGMTString();
619		} else expires = "";
620		document.cookie = name + "=" + value + expires + "; path=/";
621	}
622	
623    // Fix for hiding Content till page is loaded
624	$(document).ready(function() {
625		$('.hide-cookie-content').removeClass("hide-cookie-content");
626	});
627});   
628/* End JS for preset "Cookie Consent Bar V3" */

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.