PageSourceSearch

https://www.johnbward.com/scripts/service-areas.js

js johnbward.com collected 2026-10-07 22:48:05 UTC 2,106 bytes, 90 lines download raw bytes

1/** Service area pages — scroll reveal + case-study carousels. */
2(function () {
3	function initReveal() {
4		document.documentElement.classList.add('jbw-anim');
5
6		var targets = document.querySelectorAll('.jbw-sa [data-reveal]');
7		if (!targets.length) return;
8
9		function markInView(el) {
10			var rect = el.getBoundingClientRect();
11			return rect.top < window.innerHeight * 0.92 && rect.bottom > 0;
12		}
13
14		if (!('IntersectionObserver' in window)) {
15			targets.forEach(function (el) {
16				el.classList.add('is-inview');
17			});
18			return;
19		}
20
21		var observer = new IntersectionObserver(
22			function (entries) {
23				entries.forEach(function (entry) {
24					if (entry.isIntersecting) {
25						entry.target.classList.add('is-inview');
26						observer.unobserve(entry.target);
27					}
28				});
29			},
30			{ rootMargin: '0px 0px -8% 0px', threshold: 0.08 }
31		);
32
33		targets.forEach(function (el) {
34			if (markInView(el)) {
35				el.classList.add('is-inview');
36			} else {
37				observer.observe(el);
38			}
39		});
40	}
41
42	function initCarousels() {
43		var carousels = document.querySelectorAll('[data-jbw-carousel]');
44		carousels.forEach(function (carousel) {
45			var slides = carousel.querySelectorAll('[data-jbw-slide]');
46			if (slides.length < 2) return;
47
48			var index = 0;
49			var interval = 6000;
50
51			function show(next) {
52				slides[index].classList.remove('is-active');
53				index = next;
54				slides[index].classList.add('is-active');
55			}
56
57			function tick() {
58				show((index + 1) % slides.length);
59			}
60
61			var timer = setInterval(tick, interval);
62
63			carousel.addEventListener('mouseenter', function () {
64				clearInterval(timer);
65			});
66			carousel.addEventListener('mouseleave', function () {
67				timer = setInterval(tick, interval);
68			});
69
70			document.addEventListener('visibilitychange', function () {
71				if (document.hidden) {
72					clearInterval(timer);
73				} else {
74					timer = setInterval(tick, interval);
75				}
76			});
77		});
78	}
79
80	function init() {
81		initReveal();
82		initCarousels();
83	}
84
85	if (document.readyState === 'loading') {
86		document.addEventListener('DOMContentLoaded', init);
87	} else {
88		init();
89	}
90})();

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.