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.