PageSourceSearch

https://www.hockeytime.net/_av_share/branches/beta/wp_themes/seaml…/assets/js/av-carousel.js?t=1699977716

js hockeytime.net collected 2026-10-02 12:50:09 UTC 6,733 bytes, 220 lines download raw bytes

1/**
2 * This methods is the main controller for AV Carousel Elements
3 * It automatically builds carousels tagged with data-av-carousel attribute
4 * Starts after DOMLoaded event and relies on PHP output from WP Customizer
5 *
6 * If there are less than 4 elements (via PHP) it will stop immediately
7 */
8(function () {
9	// Add OnDOMLoaded AV Carousel Preparation
10	if (document.readyState === 'loading') {
11		document.addEventListener('DOMContentLoaded', makeAVCarousels);
12	} else {
13		makeAVCarousels();
14	}
15
16	function makeAVCarousels() {
17		// Get all carousels in page on DOM Loaded
18		let carousels = document.querySelectorAll('[data-av-carousel]');
19
20		// Enable all carousels in page
21		carousels.forEach(carousel => {
22
23			// If there are too few articles in the carousel, disable the system entirely
24			// Set first slide as active to allow displaying content even if disabled
25			if (carousel.classList.contains("not-enough-articles")) {
26				carousel.querySelector(".av-carousel-slide").classList.add("slide-active");
27				return;
28			}
29
30			// Declare some data
31			let container = carousel.querySelector(".av-carousel-slides");
32			let leftButton = carousel.querySelector(".av-carousel-button.left");
33			let rightButton = carousel.querySelector(".av-carousel-button.right");
34			let slides = container.querySelectorAll(".av-carousel-slide");
35			let dots = carousel.querySelector(".av-carousel-dots");
36			let isAnimating = false;
37			let autoSlidingInterval;
38			let slidingDirection = false;
39
40			// Set first slide as active and get first and last one
41			let activeSlide = slides[0];
42			let firstSlide = slides[0];
43			let lastSlide = slides[slides.length - 1];
44			activeSlide.classList.add("slide-active");
45
46			// Mark all slides
47			enumSlides();
48
49			// Add transition class after a few millisec to enable transitions and avoid repaints
50			setTimeout(() => {container.classList.add("transitions-enabled")}, 100);
51
52			// Main animation function
53			function slideTo(dir) {
54				// Avoid running if already animating
55				if (isAnimating) return;
56
57				// Save sliding direction and set flag
58				isAnimating = true;
59				slidingDirection = dir;
60
61				// Make buttons fade a bit and avoid clicks
62				leftButton.classList.add("disabled");
63				rightButton.classList.add("disabled");
64
65				// Switch based on direction:
66				// Going right -> We need to pop the last slide to first position before animation
67				// Going left  -> No problem: we always have a next slide
68				let nextActiveSlide = activeSlide.nextElementSibling;
69				if (dir === "right") {
70					moveLastSlideFirst();
71					nextActiveSlide = activeSlide.previousElementSibling;
72				}
73
74				// Slide to right or left after allowing DOM to setup
75				setTimeout(() => {
76					activeSlide.classList.remove("slide-active");
77					activeSlide = nextActiveSlide;
78					activeSlide.classList.add("slide-active");
79				}, 20);
80
81				// Dots system (if present)
82				if (dots) {
83					let currDot = dots.querySelector(".active");
84					let nextDot = dir === "left" ? currDot.nextElementSibling : currDot.previousElementSibling;
85					if (!nextDot) {
86						// Reached limit: rewind dots
87						nextDot = dir === "left" ? dots.firstChild : dots.lastChild;
88					}
89
90					// Move active class
91					currDot.classList.remove("active");
92					nextDot.classList.add("active");
93				}
94			}
95
96			// Manage Animation End for current slide
97			container.addEventListener("transitionend", (e) => {
98
99				// Only trigger event on active slide
100				if (!e.target.classList.contains("slide-active")) return;
101
102				// Reset slide numeration
103				enumSlides();
104
105				// If slide current active index is > 0 there is a leftover slide at the beginning
106				// Proceed moving this slide at the end and enumerate again
107				if (e.target.dataset.index > 0) {
108					moveFirstSlideLast();
109					enumSlides();
110				}
111
112				// Re-enable controls
113				leftButton.classList.remove("disabled");
114				rightButton.classList.remove("disabled");
115
116				// Disable animation status
117				isAnimating = false;
118
119			});
120
121			// Enumerate and order the slides after DOM Manipulation
122			function enumSlides() {
123				slides = container.querySelectorAll(".av-carousel-slide");
124				slides.forEach((slide, i) => slide.dataset.index = i);
125			}
126
127			// Functions for moving slides order in DOM
128			function moveLastSlideFirst() {
129				let newSlide = lastSlide;
130				lastSlide = newSlide.previousElementSibling;
131				container.insertBefore(newSlide, container.firstChild);
132				firstSlide = newSlide;
133			}
134
135			function moveFirstSlideLast() {
136				let newSlide = firstSlide;
137				firstSlide = newSlide.nextElementSibling;
138				container.appendChild(newSlide);
139				lastSlide = newSlide;
140			}
141
142			// Swipe Detection System
143			function enableSwiping() {
144				// States: 0 - no swipe, 1 - swipe started, 2 - swipe released
145				let swipeState = 0;
146				let threshold = 80;
147				let startX = 0;
148				let pixelOffsetX = 0;
149
150				// Bind and unbind methods
151				function addListenerMulti(el, list, fn) {
152					list.split(' ').forEach(e => el.addEventListener(e, fn, {capture: false, passive: true}));
153				}
154
155				addListenerMulti(carousel, 'mousedown touchstart', swipeStart);
156				addListenerMulti(carousel, 'mouseup touchend', swipeEnd);
157				addListenerMulti(carousel, 'mousemove touchmove', swiping);
158
159				// Swipe Functions
160				function swipeStart(event) {
161					if (event.touches)
162						event = event.touches[0];
163
164					if (swipeState === 0) {
165						swipeState = 1;
166						startX = event.screenX;
167					}
168				}
169
170				function swipeEnd() {
171					// Check if over thresholds
172					if (pixelOffsetX > threshold) {
173						manualSlide("right");
174					} else if (pixelOffsetX < -threshold) {
175						manualSlide("left");
176					}
177
178					// Reset data
179					startX = 0;
180					pixelOffsetX = 0;
181					swipeState = 0;
182				}
183
184				function swiping(event) {
185					if (swipeState === 1 || swipeState === 2) {
186						if (event.touches)
187							event = event.touches[0];
188						pixelOffsetX = event.screenX - startX;
189					}
190				}
191			}
192
193			// Bind click events only when not disabled
194			leftButton.onclick  = () => manualSlide("right");
195			rightButton.onclick = () => manualSlide("left");
196
197			function manualSlide(direction) {
198				// Avoid click resetting timer if already animating
199				if (isAnimating) return;
200
201				// Reset auto scrolling to 0 if enabled
202				if (carousel.classList.contains("av-carousel-autoplay")) {
203					clearInterval(autoSlidingInterval);
204					autoSlidingInterval = setInterval(() => { slideTo("left"); }, 8000);
205				}
206
207				// Do the slide
208				slideTo(direction);
209			}
210
211			// Enable Touch/Mouse Swiping
212			enableSwiping();
213
214			// Set auto scrolling every 8 seconds if enabled
215			if (carousel.classList.contains("av-carousel-autoplay"))
216				autoSlidingInterval = setInterval(() => { slideTo("left"); }, 8000);
217
218		});
219	}
220})();

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.