PageSourceSearch

https://cdn.clarku.edu/news/wp-content/plugins/clarku-hero/js/flairousel.js?ver=1.12

js clarku.edu collected 2026-09-24 06:20:33 UTC 6,101 bytes, 249 lines download raw bytes

1/**
2 * 
3 */
4( function() {
5
6	var carousels;
7	
8	document.addEventListener( "DOMContentLoaded", initCarousel );
9	
10	function initCarousel() {
11
12		carousels = document.querySelectorAll( ".flairousel" );
13				
14		carousels.forEach( function( el ) {
15			observe( el );
16			var w = wrapCarousel( el );
17			// w.dataset.slideDist = getSlideDistance( w );
18			addPrevNextButtons( w );
19			addDots( w );
20			updateButtons( w );
21						
22		});
23		
24	}
25	
26	function getSlideDistance( el ) {
27		var cols = el.querySelectorAll( ".flairousel > div" );
28		var cols = [...cols];
29
30		var rect = cols[0].getBoundingClientRect();
31		var rect2 = cols[1].getBoundingClientRect();
32
33		return (rect2.width - ( rect.width + rect.left )) * -1;
34
35	}
36	
37	function observe( el ) {
38		var rect = el.getBoundingClientRect();
39
40		if ('IntersectionObserver' in window) {
41			var options = {
42				root: el,
43				rootMargin: '0px',
44				threshold: [0, 0.2, 0.6, 0.8, 1]
45// 				threshold: buildThreshold( ( rect.width / 60 ) )
46			}
47			var observer = new IntersectionObserver(observerCallback, options);
48			var els = el.querySelectorAll(":scope > div");
49			
50			els.forEach(function( el ) {
51				observer.observe(el);
52			});
53		}
54	}
55	
56	function observerCallback(entries, observer) {
57		entries.every(function(entry) {
58			entry.target.dataset.intersection = entry.intersectionRatio;
59			entry.target.dataset.isIntersecting = entry.isIntersecting;
60			if( entry.intersectionRatio > .6 ) {
61				var c = entry.target.parentNode;
62				var wrap = c.parentNode;
63				var index = Array.prototype.indexOf.call( c.children, entry.target );
64
65				// this is where the dots are getting messed up on doubles and triples...
66				// we need this to "auto-detect" the slide position when the user scrolls
67				// but it misbehaves when a the user clicks a dot/button
68				// the "fix" is the callbackCallBack function that limits execution 
69				// to just the last iteration.
70				// it mostly works
71				// wrap.dataset.slideIndex = index;
72	 			// updateButtons( wrap );
73				return false;
74			}
75			return true;
76		});
77		callbackCallBack(entries[0].target.parentNode);
78	}
79	
80	function callbackCallBack( carousel ) {
81			var els = carousel.querySelectorAll(":scope > div");			
82			els = [...els];
83			els.every(function( el ) {
84				if( el.dataset.intersection > .6 && el.dataset.isIntersecting ) {
85
86					var wrap = carousel.parentNode;
87					var index = Array.prototype.indexOf.call( carousel.children, el );
88					wrap.dataset.slideIndex = index;
89
90					updateButtons( wrap );
91					return false;
92				}
93				return true;
94			});
95	}
96	
97	function buildThreshold(num) {
98		let thresholds = [];
99
100		for (let i=1.0; i<=num; i++) {
101			let ratio = i/num;
102			thresholds.push(ratio);
103		}
104
105		thresholds.push(0);
106		return thresholds;
107	}
108
109
110	function updatePosition( el ) {
111		var xer = (el.dataset.xer * 1);
112		// sanity check
113		var index = el.dataset.slideIndex;
114		if ( index < 0 ) {
115			index = 0;
116			el.dataset.slideIndex = index;
117		}
118		var max = ( el.dataset.slideCount * 1 ) + 1 - xer;
119		el.dataset.max = max;
120		if ( index > max ) {
121			index = max;
122			el.dataset.slideIndex = index;
123		}
124		// end sanity check
125
126		var c = el.querySelector( ".flairousel" );
127		var rect = el.getBoundingClientRect();
128		var dist = rect.width / (el.dataset.xer * 1);
129		c.scrollLeft = dist * index;
130
131
132// 		c.scrollLeft = Math.floor( el.dataset.slideDist * index );
133
134		// updateButtons( el ); // IntersectionObserver handles this
135	}
136	
137	function updateButtons( el ) {
138		var xer = el.dataset.xer * 1;
139		var dots = el.querySelectorAll( ".dot" );
140		dots.forEach( function( d ) {
141			if( d.dataset.slideIndex == el.dataset.slideIndex ) {
142				d.dataset.isSelected = 1;
143			} else {
144				d.dataset.isSelected = 0;
145			}
146		});
147		
148		var p = el.querySelector(".previous");
149		var n = el.querySelector(".next");
150		p.classList.remove('disabled');
151		n.classList.remove('disabled');
152		if( 0 == el.dataset.slideIndex ) {
153			p.classList.add('disabled');
154		}
155		if( el.dataset.slideCount-xer == el.dataset.slideIndex ) {
156			n.classList.add('disabled');
157		}
158		
159	}
160	
161	
162	function wrapCarousel( el ) {
163		var wrap = document.createElement("DIV");
164		wrap.classList.add("flairousel-wrap");
165		el.parentNode.insertBefore( wrap, el );		
166		wrap.appendChild( el );
167		
168		var slides = el.querySelectorAll(":scope > div");		
169		wrap.dataset.slideCount = slides.length;
170		wrap.dataset.slideIndex = 0;
171		
172		wrap.dataset.xer = 1;
173		var rect = wrap.getBoundingClientRect();
174		
175		if( rect.width > 400 && el.classList.contains( "double" ) ) {
176			wrap.dataset.xer = 2;
177		}
178
179		// this is a pretty kludgy way to manage responsive columns
180		// maybe css vars would be better, ala el.setProperty( '--foo', bar );
181		if( el.classList.contains( "triple" ) ) {
182			if ( rect.width > 640 ) {
183				wrap.dataset.xer = 3;
184			} else {
185				el.classList.remove( "triple" );
186				el.classList.add( "double" );
187				wrap.dataset.xer = 2;
188			}
189		}
190
191		return wrap;
192	}
193
194	
195	function addDots( el ) {
196		var dot, c, dots, slides, i;
197		
198		c = el.querySelector( ".carousel" );
199		
200		dots = document.createElement("DIV");
201		dots.classList.add("dots");
202		el.appendChild(dots);
203		el.classList.add("has-dots");
204				
205		for( i=0; i<el.dataset.slideCount; i++ ) {
206			(function(i){
207				dot = document.createElement("BUTTON");
208				dot.classList.add("dot");
209				dot.dataset.slideIndex = i;
210				dot.addEventListener( "click", function() {
211					el.dataset.slideIndex = i;
212					updatePosition( el );
213				});
214				dots.appendChild(dot);
215			})(i)
216		}
217
218	}
219	
220	
221	function addPrevNextButtons( el ) {
222		var f, r;
223		var c = el.querySelector( ".flairousel" );
224		var xer = (el.dataset.xer * 1);
225		r = document.createElement("BUTTON");
226		r.innerHTML = "Previous";
227		r.classList.add("previous");
228		r.addEventListener( "click", function() {
229			el.dataset.slideIndex = (el.dataset.slideIndex*1) - xer;
230			updatePosition( el );
231		});
232		el.appendChild(r);
233
234		f = document.createElement("BUTTON");
235		f.innerHTML = "Next";
236		f.classList.add("next");
237		f.addEventListener( "click", function() {
238			el.dataset.slideIndex = (el.dataset.slideIndex*1) + xer;
239			updatePosition( el );
240		});
241		el.appendChild(f);
242
243		el.classList.add("has-buttons");
244
245	}
246	
247
248
249})();

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.