PageSourceSearch

https://cdn.clarku.edu/wp-content/plugins/clarku-component-library/pattern-lib/js/sticky.js?ver=2.1

js clarku.edu collected 2026-10-01 06:30:58 UTC 2,444 bytes, 103 lines download raw bytes

1( function() {
2
3	var origin, position, stickyNav;
4	var links = [];
5	var anchors = [];
6	var margin = 10;
7
8	document.addEventListener( "DOMContentLoaded", initSticky );
9	
10	function initSticky() {
11
12		stickyNav = document.querySelector( "nav.sticky" );
13		if ( ! stickyNav ) { return false }
14		origin = stickyNav.getBoundingClientRect().top;
15
16		document.querySelector( "html" ).classList.add( "has-sticky-nav" );
17		links = stickyNav.querySelectorAll( "a" );
18		links.forEach(function(el, i) {
19			el.addEventListener( "click", handleClick );
20			var t = document.getElementById( el.getAttribute( "href" ).replace( "#", "" ) );
21			if( t ) {
22				t.classList.add("sticky-anchor");
23				anchors.push( t );
24			}
25		});
26		
27		
28		window.addEventListener("scroll", testSticky);
29
30		if("IntersectionObserver" in window) {
31			let options = {
32				root: null,
33				rootMargin: "-" + margin + "px",
34				threshold: 1
35			}
36			let observer = new IntersectionObserver(observerCallback, options);
37
38			anchors.forEach(function(el) {
39				observer.observe(el);
40			});
41		}
42	}
43
44	function observerCallback(entries, observer) {
45		entries.forEach(function(entry) {
46			var top = entry.boundingClientRect.top;
47			entry.target.dataset.stickyFromTop = top;
48			
49 			// we need the last link where top < 0
50			var activeSection;						
51			for( var i = anchors.length - 1; i >= 0; i-- ) {
52				if( ( anchors[i].dataset.stickyFromTop * 1 ) < ( margin + 1 ) ) { 
53					activeSection = anchors[i];
54					break;
55				}
56			}
57			var l = null;
58			if( !! activeSection ) {
59				l = stickyNav.querySelector("[href='#" + activeSection.id + "']");
60			}
61			activateLink( l );
62			
63		});
64 	}
65
66	function activateLink(l) {
67		links.forEach(function(el, i) {
68			el.classList.remove("active");
69		});
70		if( l ) {
71			l.classList.add("active");
72		}
73	}
74	
75	function handleClick(e) {
76		e.preventDefault();
77		var destination = document.querySelector( this.getAttribute("href") );
78		if( destination ) {
79			document.querySelector( this.getAttribute("href") ).scrollIntoView({
80				behavior: "smooth"
81			});
82			activateLink(this);
83		} else {
84			// bad link
85			if( this.classList.contains("bad") ) {
86				this.classList.remove("bad");
87				this.offsetHeight; // trigger a reflow to restart animation on consecutive clicks
88			}
89			this.classList.add("bad");
90		}
91	}
92
93	
94	function testSticky() {
95		if( window.scrollY >= origin ) {
96			stickyNav.classList.add("fixed");
97		} else {
98			stickyNav.classList.remove("fixed");
99		}
100	}
101	
102
103})();

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.