PageSourceSearch

https://platformday.com/assets/js/main.js

js platformday.com collected 2026-09-27 09:48:22 UTC 6,637 bytes, 190 lines download raw bytes

1"use strict";
2
3/* ======= Header animation ======= */   
4const header = document.getElementById('header');  
5
6window.onload=function() 
7{   
8    headerAnimation(); 
9
10};
11
12window.onresize=function() 
13{   
14    headerAnimation(); 
15
16}; 
17
18window.onscroll=function() 
19{ 
20    headerAnimation(); 
21
22}; 
23    
24
25function headerAnimation () {
26
27    var scrollTop = window.scrollY;
28	
29	if ( scrollTop > 100 ) {	    
30	    header.classList.add('header-shrink');    
31	    	    
32	} else {
33	    header.classList.remove('header-shrink');
34	}
35
36};
37
38/* ===== Sponsor links jump, never glide (Marek 2026-09-21) ===== */
39/* "Sponsor" buttons and nav links (#sponsor on home pages, #sponsors on event pages) used to start a smooth scroll
40   while the lead form's "Email us" panel was animating open and lazy images were still arriving above: the page
41   grew under the glide and it sometimes stopped half way. They now teleport: the panel opens without its
42   transition, the page jumps in the same tick, and the landing is re-checked once shortly after and once on load
43   unless the visitor has touched the page. Every other anchor keeps its smooth scroll. Never throws. */
44(function () {
45	try {
46		var target = document.getElementById('sponsor') || document.getElementById('sponsors');
47		if (!target) return;
48		var hash = '#' + target.id;
49		var touched = false;
50		['wheel', 'touchmove', 'keydown', 'pointerdown'].forEach(function (t) {
51			window.addEventListener(t, function () { touched = true; }, { passive: true, capture: true });
52		});
53
54		function openLeadPanel() {
55			var panel = document.getElementById('lead-panel');
56			if (!panel || typeof window.leadOpen !== 'function') return;
57			var was = panel.style.transition;
58			panel.style.transition = 'none';
59			window.leadOpen();
60			void panel.offsetHeight;                                 // apply the open state before the transition returns
61			panel.style.transition = was;
62		}
63		function land() {
64			var margin = parseFloat(getComputedStyle(target).scrollMarginTop);
65			var offset = margin > 0 ? margin : 69;                   // 69 = header height, same as the .scrollto handler
66			var y = Math.max(0, Math.round(target.getBoundingClientRect().top + window.pageYOffset - offset));
67			if (Math.abs(window.pageYOffset - y) > 1) window.scrollTo({ top: y, left: 0, behavior: 'instant' });
68		}
69		function sponsorJump() {
70			openLeadPanel();
71			land();
72			touched = false;
73			setTimeout(function () { if (!touched) land(); }, 300);
74		}
75		function closeMenu() {
76			if (typeof closeMobileNav === 'function') return closeMobileNav();
77			var nav = document.getElementById('navigation');
78			if (nav && nav.classList.contains('show')) nav.classList.remove('show');
79		}
80
81		document.querySelectorAll('a[href="' + hash + '"]').forEach(function (a) {
82			a.addEventListener('click', function (e) {
83				e.preventDefault();
84				e.stopImmediatePropagation();                        // not the smooth .scrollto handler, not the animated leadOpen
85				if (history.pushState) history.pushState(null, '', hash);
86				sponsorJump();
87				closeMenu();
88			}, true);
89		});
90
91		// arriving with the hash (talk page hero button -> ./#sponsors, navbar from a subpage, a shared link)
92		if (location.hash === hash) {
93			var arrive = function () { if (!touched) { openLeadPanel(); land(); } };
94			if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', arrive); else arrive();
95			window.addEventListener('load', arrive);
96		}
97	} catch (e) {}
98})();
99
100
101/* ===== Smooth scrolling ====== */
102/*  Note: You need to include smoothscroll.min.js (smooth scroll behavior polyfill) on the page to cover some browsers */
103/* Ref: https://github.com/iamdustan/smoothscroll */
104
105
106let scrollLinks = document.querySelectorAll('.scrollto');
107const pageNavWrapper = document.getElementById('navigation');
108
109scrollLinks.forEach((scrollLink) => {
110
111	scrollLink.addEventListener('click', (e) => {
112		
113		e.preventDefault();
114
115		let element = document.querySelector(scrollLink.getAttribute("href"));
116		
117		const yOffset = 69; //page .header height
118		
119		//console.log(yOffset);
120		
121		const y = element.getBoundingClientRect().top + window.pageYOffset - yOffset;
122		
123		window.scrollTo({top: y, behavior: 'smooth'});
124		history.pushState(null, null, scrollLink.getAttribute("href"));
125		
126		
127		//Collapse mobile menu after clicking
128		closeMobileNav();
129
130		
131    });
132	
133});
134    
135
136/* ===== Mobile menu ===== */
137/* Collapse the open hamburger menu. Used by the .scrollto handler above and by a delegated
138   handler below, so plain nav-link anchors (sreday home, all event pages) close it too. */
139function closeMobileNav() {
140	if (!pageNavWrapper || !pageNavWrapper.classList.contains('show')) return;
141	if (window.bootstrap && bootstrap.Collapse) {
142		bootstrap.Collapse.getOrCreateInstance(pageNavWrapper, { toggle: false }).hide();
143	} else {
144		pageNavWrapper.classList.remove('show');
145	}
146}
147if (pageNavWrapper) {
148	pageNavWrapper.addEventListener('click', (e) => { if (e.target.closest('a')) closeMobileNav(); });
149}
150
151/* ===== Navbar glow ===== */
152// A soft vertical flare behind the glassy navbar that follows the mouse (styles: "NAVBAR GLOW" in the css).
153// Desktop pointers only; the beam eases towards the cursor so it trails a little. Never throws.
154(function () {
155	try {
156		var bar = document.getElementById('header') || document.querySelector('.navbar.fixed-top');
157		if (!bar || !window.matchMedia || !window.requestAnimationFrame) return;
158		if (!window.matchMedia('(hover: hover) and (pointer: fine)').matches) return;
159		var still = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
160		var wrap = document.createElement('div'), beam = document.createElement('i');
161		wrap.className = 'nav-glow'; wrap.setAttribute('aria-hidden', 'true'); wrap.appendChild(beam);
162		bar.insertBefore(wrap, bar.firstChild);
163		var x = null, target = 0, raf = 0;
164		function frame() {
165			raf = 0;
166			x += (target - x) * 0.16;
167			if (Math.abs(target - x) < 0.4) x = target;
168			beam.style.transform = 'translate3d(' + x.toFixed(1) + 'px,0,0)';
169			if (x !== target) raf = window.requestAnimationFrame(frame);
170		}
171		bar.addEventListener('mousemove', function (e) {
172			target = e.clientX - bar.getBoundingClientRect().left;
173			if (x === null || still) x = target;
174			wrap.classList.add('on');
175			if (!raf) raf = window.requestAnimationFrame(frame);
176		});
177		bar.addEventListener('mouseleave', function () { wrap.classList.remove('on'); });
178	} catch (e) {}
179})();
180
181/* ===== Gumshoe SrollSpy ===== */
182/* Ref: https://github.com/cferdinandi/gumshoe  */
183// Get the sticky header
184
185
186// Initialize Gumshoe
187var spy = new Gumshoe('#navigation a', {
188	offset: 69 //page .header heights
189});
190

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.