PageSourceSearch

https://hostandkeep.com/wp-content/plugins/fs-marquee/includes/app…/assets/js/fs-marquee.js?v=1.0.0&ver=4.5.24

js hostandkeep.com collected 2026-09-24 11:31:25 UTC 5,909 bytes, 145 lines download raw bytes

1document.addEventListener("DOMContentLoaded", () => {
2
3    function initializeMarquees() {
4
5        // Select all elements with the class 'fs-marquee'
6        const marquees = document.querySelectorAll('.fs-marquee');
7
8        /**
9         * Calculate the total width of all marquee items and update CSS properties.
10         * @param {HTMLElement} marquee - The marquee element.
11         * @param {HTMLElement} container - The container element within the marquee.
12         * @param {NodeList} items - Collection of items within the container.
13         * @param {HTMLElement} progress - The progress element if available.
14         */
15        const calculateWidth = (marquee, container, items, progress) => {
16            try {
17                const totalWidth = Array.from(items).reduce((total, item) => {
18                    if (!item.hasAttribute('aria-hidden')) {
19                        // Use offsetWidth for more reliable width calculation
20                        return total + item.offsetWidth;
21                    }
22                    return total;
23                }, 0);
24
25                // Set CSS custom property for the total width
26                marquee.style.setProperty('--fs-marquee-total-width', `-${totalWidth.toFixed(3)}px`);
27                resumeAnimations(container, progress);
28            } catch (error) {
29                console.error("Error calculating marquee width:", error);
30            }
31        };
32
33        /**
34         * Pause animations for both container and progress elements.
35         * @param {HTMLElement} container - The container element of marquee items.
36         * @param {HTMLElement} progress - The progress bar, if available.
37         */
38        const pauseAnimations = (container, progress) => {
39            container.style.animationPlayState = 'paused';
40            if (progress) progress.style.animationPlayState = 'paused';
41        };
42
43        /**
44         * Resume animations for both container and progress elements.
45         * @param {HTMLElement} container - The container element of marquee items.
46         * @param {HTMLElement} progress - The progress bar, if available.
47         */
48        const resumeAnimations = (container, progress) => {
49            container.style.animationPlayState = 'running';
50            if (progress) progress.style.animationPlayState = 'running';
51        };
52
53        /**
54         * Debounce utility function to limit the rate of execution.
55         * @param {Function} fn - The function to debounce.
56         * @param {number} delay - The debounce delay in milliseconds.
57         * @returns {Function} - A debounced version of the input function.
58         */
59        const debounce = (fn, delay) => {
60            let timeoutId;
61            return (...args) => {
62                clearTimeout(timeoutId);
63                timeoutId = setTimeout(() => fn.apply(this, args), delay);
64            };
65        };
66
67        // Initialize marquees
68        marquees.forEach(marquee => {
69            const container = marquee.querySelector('.fs-marquee-items');
70            const items = marquee.querySelectorAll('.fs-marquee-items > .fs-marquee-item:not([aria-hidden])');
71            const progress = marquee.querySelector('.fs-marquee-progress');
72
73            if (!container || items.length === 0) return; // Exit if no valid container or items
74
75            let lastWindowWidth = window.innerWidth;  // Track width per marquee
76
77            const startCalculation = () => {
78                calculateWidth(marquee, container, items, progress);
79            };
80
81            // Use ResizeObserver to dynamically handle container size changes
82            const resizeObserver = new ResizeObserver(() => {
83                if (resizeObserverActive) {
84                    startCalculation();
85                }
86            });
87
88            // Observe changes in the marquee container
89            try {
90                resizeObserver.observe(container);
91            } catch (error) {
92                console.error('Failed to observe marquee container:', error);
93            }
94
95            let resizeObserverActive = true;
96
97            const handleResize = debounce(() => {
98                startCalculation();
99                resumeAnimations(container, progress);
100                if (!resizeObserverActive) {
101                    resizeObserver.observe(container);
102                    resizeObserverActive = true;
103                }
104            }, 500);
105
106            // Add resize event listener for each marquee
107            window.addEventListener('resize', () => {
108                const currentWindowWidth = window.innerWidth;
109
110                if (currentWindowWidth !== lastWindowWidth) {
111                    pauseAnimations(container, progress);
112
113                    if (resizeObserverActive) {
114                        resizeObserver.disconnect();
115                        resizeObserverActive = false;
116                    }
117
118                    handleResize();
119                    lastWindowWidth = currentWindowWidth;
120                }
121            });
122
123            // Detect when the browser tab becomes active
124            document.addEventListener('visibilitychange', () => {
125                if (!document.hidden) {
126                    startCalculation();
127                    resumeAnimations(container, progress);
128                } else {
129                    startCalculation();
130                    pauseAnimations(container, progress);
131                }
132            });
133
134            // Recalculate when fonts are loaded (important for accurate text sizing)
135            document.fonts.ready.then(() => {
136                startCalculation();
137            });
138
139        });
140    }
141
142    // Wait until the window is fully loaded before initializing marquees
143    window.onload = initializeMarquees;
144
145});

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.