PageSourceSearch

https://latteeluna.com/themes/latteeluna/assets/js/slider-video.js

js latteeluna.com collected 2026-10-10 01:26:49 UTC 10,213 bytes, 260 lines download raw bytes

1/**
2 * Gestione video nello slider
3 * Gestisce la riproduzione automatica dei video quando le slide diventano attive
4 */
5
6(function() {
7    'use strict';
8
9    /**
10     * Inizializza la gestione video nello slider
11     */
12    function initSliderVideos() {
13        const sliderContainer = document.querySelector('.homeslider-container');
14        
15        if (!sliderContainer) {
16            return;
17        }
18
19        const slides = sliderContainer.querySelectorAll('.slide');
20        const videos = sliderContainer.querySelectorAll('.slide-video-element');
21        
22        if (videos.length === 0) {
23            return;
24        }
25
26        // Pausa tutti i video inizialmente e gestisci fallback
27        videos.forEach(function(video) {
28            video.pause();
29            video.currentTime = 0;
30            
31            // Se ha data-src, convertilo in src immediatamente (non aspettare lazy loading)
32            if (video.dataset.src && !video.src) {
33                video.src = video.dataset.src;
34                const sources = video.querySelectorAll('source[data-src]');
35                sources.forEach(function(source) {
36                    source.src = source.dataset.src;
37                    source.removeAttribute('data-src');
38                });
39                video.removeAttribute('data-src');
40            }
41            
42            // Gestisci errori del video - mostra sempre il fallback se il video fallisce
43            const slide = video.closest('.slide');
44            const fallbackImage = slide ? slide.querySelector('.slide-fallback-image') : null;
45            
46            video.addEventListener('error', function() {
47                video.classList.add('error');
48                if (fallbackImage) {
49                    fallbackImage.style.opacity = '1';
50                    fallbackImage.style.pointerEvents = 'auto';
51                }
52            }, { once: true });
53        });
54
55        // Funzione per gestire il cambio slide
56        function handleSlideChange() {
57            // Trova la slide attiva cercando la classe che finisce in _on
58            let activeSlide = null;
59            
60            slides.forEach(function(slide) {
61                const classList = Array.from(slide.classList);
62                const hasOnClass = classList.some(function(className) {
63                    return className.endsWith('_on');
64                });
65                if (hasOnClass) {
66                    activeSlide = slide;
67                }
68            });
69            
70            // Fallback: prima slide
71            if (!activeSlide) {
72                activeSlide = slides[0];
73            }
74            
75            if (!activeSlide) {
76                return;
77            }
78
79            // Pausa tutti i video
80            videos.forEach(function(video) {
81                video.pause();
82                video.currentTime = 0;
83            });
84
85            // Trova il video nella slide attiva
86            const activeVideo = activeSlide.querySelector('.slide-video-element');
87            const fallbackImage = activeSlide.querySelector('.slide-fallback-image');
88            
89            if (activeVideo) {
90                // Se ha data-src, convertilo in src (per lazy loading)
91                if (activeVideo.dataset.src && !activeVideo.src) {
92                    activeVideo.src = activeVideo.dataset.src;
93                    // Aggiorna anche i source elements
94                    const sources = activeVideo.querySelectorAll('source[data-src]');
95                    sources.forEach(function(source) {
96                        source.src = source.dataset.src;
97                        source.removeAttribute('data-src');
98                    });
99                    activeVideo.removeAttribute('data-src');
100                    activeVideo.load();
101                }
102                
103                // Rimuovi listener errori precedenti e aggiungi nuovo
104                const newErrorHandler = function() {
105                    activeVideo.classList.add('error');
106                    if (fallbackImage) {
107                        fallbackImage.style.opacity = '1';
108                        fallbackImage.style.pointerEvents = 'auto';
109                    }
110                };
111                activeVideo.removeEventListener('error', newErrorHandler);
112                activeVideo.addEventListener('error', newErrorHandler, { once: true });
113                
114                // Funzione per riprodurre il video
115                const playVideo = function() {
116                    activeVideo.play().catch(function(error) {
117                        console.log('Video autoplay prevented:', error);
118                        if (fallbackImage) {
119                            fallbackImage.style.opacity = '1';
120                            fallbackImage.style.pointerEvents = 'auto';
121                        }
122                    });
123                };
124                
125                // Carica e riproduci il video
126                if (activeVideo.readyState >= 2) {
127                    // Video già caricato - riproduci subito
128                    playVideo();
129                } else if (activeVideo.readyState >= 1) {
130                    // Video ha caricato i metadati
131                    playVideo();
132                } else {
133                    // Carica il video prima di riprodurlo
134                    activeVideo.load();
135                    activeVideo.addEventListener('loadeddata', playVideo, { once: true });
136                    activeVideo.addEventListener('canplay', playVideo, { once: true });
137                }
138            } else if (fallbackImage) {
139                // Se non c'è video, assicurati che l'immagine sia visibile
140                fallbackImage.style.opacity = '1';
141                fallbackImage.style.pointerEvents = 'auto';
142            }
143        }
144
145        // Traccia la slide attiva precedente per evitare chiamate duplicate
146        let previousActiveSlideId = null;
147        
148        // Funzione migliorata che evita chiamate duplicate
149        const handleSlideChangeDebounced = function() {
150            // Trova la slide attiva cercando la classe che finisce in _on
151            let activeSlide = null;
152            
153            // Cerca slide con classe che finisce in _on (es: homeslider1_on)
154            slides.forEach(function(slide) {
155                const classList = Array.from(slide.classList);
156                const hasOnClass = classList.some(function(className) {
157                    return className.endsWith('_on');
158                });
159                if (hasOnClass) {
160                    activeSlide = slide;
161                }
162            });
163            
164            // Se non trovata, usa la prima slide
165            if (!activeSlide) {
166                activeSlide = slides[0];
167            }
168            
169            if (!activeSlide) {
170                return;
171            }
172            
173            // Se la slide attiva è la stessa di prima, non fare nulla
174            const currentSlideId = activeSlide.id || activeSlide.getAttribute('id');
175            if (currentSlideId === previousActiveSlideId) {
176                return;
177            }
178            
179            // Aggiorna la slide precedente
180            previousActiveSlideId = currentSlideId;
181            
182            // Esegui il cambio slide
183            handleSlideChange();
184        };
185
186        // Osserva i cambiamenti nello slider usando MutationObserver
187        if (window.MutationObserver) {
188            const observer = new MutationObserver(function(mutations) {
189                let shouldTrigger = false;
190                mutations.forEach(function(mutation) {
191                    if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
192                        // Controlla se è stata aggiunta o rimossa una classe che finisce in _on
193                        const target = mutation.target;
194                        const classList = Array.from(target.classList);
195                        const hasOnClass = classList.some(function(className) {
196                            return className.endsWith('_on');
197                        });
198                        if (hasOnClass) {
199                            shouldTrigger = true;
200                        }
201                    }
202                });
203                
204                if (shouldTrigger) {
205                    // Debounce: aspetta un po' per assicurarsi che il cambio sia completato
206                    clearTimeout(window.sliderVideoTimeout);
207                    window.sliderVideoTimeout = setTimeout(handleSlideChangeDebounced, 100);
208                }
209            });
210
211            // Osserva tutte le slide per cambiamenti di classe
212            slides.forEach(function(slide) {
213                observer.observe(slide, {
214                    attributes: true,
215                    attributeFilter: ['class']
216                });
217            });
218        }
219
220        // Gestisci anche eventi custom del responsive slides
221        sliderContainer.addEventListener('slidechange', handleSlideChangeDebounced);
222        
223        // Gestisci il primo caricamento
224        setTimeout(handleSlideChangeDebounced, 500);
225
226        // Pausa video quando l'utente esce dalla pagina
227        document.addEventListener('visibilitychange', function() {
228            if (document.hidden) {
229                videos.forEach(function(video) {
230                    video.pause();
231                });
232            } else {
233                handleSlideChange();
234            }
235        });
236
237        // Pausa video quando la finestra perde il focus
238        window.addEventListener('blur', function() {
239            videos.forEach(function(video) {
240                video.pause();
241            });
242        });
243    }
244
245    // Avvia quando il DOM è pronto
246    if (document.readyState === 'loading') {
247        document.addEventListener('DOMContentLoaded', initSliderVideos);
248    } else {
249        // Se già caricato, aspetta che lo slider sia inizializzato
250        setTimeout(initSliderVideos, 1000);
251    }
252
253    // Re-inizializza dopo che lo slider è stato inizializzato (per jQuery responsiveSlides)
254    if (typeof jQuery !== 'undefined') {
255        jQuery(document).ready(function($) {
256            setTimeout(initSliderVideos, 1500);
257        });
258    }
259
260})();

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.