1/*SLIDE OPINIÃN*/ 2 3let swiperOpinion=new Array(); 4let indexSwiperOpinion=new Array(); 5let swiperOpinionIndividual=new Array(); 6var startX, startY, startTime; 7function initializeSwiperOpinion(cantidadElementos) { 8 if(cantidadElementos>5) 9 { 10 $(".gr_swiper_opi").each(function(element) 11 { 12 if(!indexSwiperOpinion.includes(this.id)) 13 { 14 swiperOpinion.push(new Swiper(this, { 15 effect: "coverflow", 16 coverflowEffect: { 17 rotate: 0, 18 stretch: 0, 19 depth: 700, 20 modifier: 1, 21 slideShadows: false, 22 }, 23 grabCursor: true, 24 loop: true, 25 slidesPerView: 5, 26 navigation: { 27 nextEl: ".gr_swiper-button-next-opi", 28 prevEl: ".gr_swiper-button-prev-opi", 29 }, 30 pagination: { 31 el: ".gr_pagination_opi", 32 clickable: true, // Asegúrate de que la paginación sea clickeable 33 dynamicBullets: true, 34 }, 35 on: {touchStart: function (swiper, e) { 36 //console.log('Touch start detectado', e); 37 38 // En PointerEvent, e.clientX / e.clientY están directamente disponibles 39 //XSwiper = e.clientX; 40 //YSwiper = e.clientY; 41 //TimeSwiper = Date.now(); 42 XSwiper = e.touches ? e.touches[0].clientX : e.clientX; 43 YSwiper= e.touches ? e.touches[0].clientY : e.clientY; 44 TimeSwiper = Date.now(); 45 46 47 }, 48 touchEnd: function (swiper, e) { 49 //console.log('Touch end detectado', e); 50 51 const endX = e.changedTouches ? e.changedTouches[0].clientX : e.clientX; 52 const endY = e.changedTouches ? e.changedTouches[0].clientY : e.clientY; 53 const endTime = Date.now(); 54 55 const distX = Math.abs(endX - XSwiper); 56 const distY = Math.abs(endY - YSwiper); 57 const duration = endTime - TimeSwiper; 58 59 // Si no hubo movimiento ni fue largo â TAP real 60 if (distX < 10 && distY < 10 && duration < 250) { 61 // ð¹ obtener todos los elementos bajo el punto del toque 62 const elements = document.elementsFromPoint(endX, endY); 63 64 // ð¹ filtrar slides visibles 65 const visibleSlides = elements.filter(el => 66 el.classList?.contains('swiper-slide') && 67 getComputedStyle(el).op
67acity > 0 && 68 getComputedStyle(el).pointerEvents !== 'none' 69 ); 70 71 if (!visibleSlides.length) return; 72 73 // ð¹ función auxiliar para calcular opacidad efectiva 74 function getEffectiveOpacity(el) { 75 let opacity = 1; 76 let current = el; 77 while (current && current !== document.body) { 78 const o = parseFloat(getComputedStyle(current).opacity); 79 opacity *= isNaN(o) ? 1 : o; 80 current = current.parentElement; 81 } 82 return opacity; 83 } 84 85 // ð¹ ordenar por opacidad efectiva y quedarse con el más visible 86 visibleSlides.sort((a, b) => getEffectiveOpacity(b) - getEffectiveOpacity(a)); 87 const topSlide = visibleSlides[0]; 88 89 // ð¹ buscar imagen visible dentro del slide 90 const imgs = topSlide.querySelectorAll('a'); 91 if (!imgs.length) return; 92 93 // elegir la imagen con mayor opacidad efectiva 94 const visibleImgs = Array.from(imgs) 95 .filter(img => getComputedStyle(img).display !== 'none') 96 .sort((a, b) => getEffectiveOpacity(b) - getEffectiveOpacity(a)); 97 98 const topImg = visibleImgs[0]; 99 100 if (topImg) { 101 console.log('â Tap sobre anchor visible:', topImg); 102 topImg.click(); // dispara el click de la imagen 103 } else { 104 console.log('â ï¸ No se encontró imagen visible dentro del slide.'); 105 } 106 /*const elements = document.elementsFromPoint(e.clientX, e.clientY); 107 if (!elements.length) return; 108 109 // Filtramos solo imágenes visibles 110 const images = Array.from(elements).filter(el => el.tagName === 'IMG'); 111 if (!images.length) return; 112 113 let selectedImg = null; 114 let maxOpacity = -1; 115 let minDistance = Infinity; 116 117 images.forEach(img => { 118 const effOpacity = getEffectiveOpacity(img); 119 if (effOpacity === 0) return; // saltar invisibles 120 121 // distancia al clic para desempate 122 const rect = img.getBoundingClientRect(); 123 const imgCenterX = rect.left + rect.width / 2; 124 const imgCenterY = rect.top + rect.height / 2; 125 const dx = endX - imgCenterX; 126 const dy = endY - imgCenterY; 127 const distance = Math.sqrt(dx*dx + dy*dy); 128 129 // Prioridad: mayor opacidad, luego menor distancia 130 if (effOpacity > maxOpacity || (effOpacity === maxOpacity && distance < minDistance)) { 131 maxOpacity = effOpacity; 132 minDistance = distance; 133 selectedImg = img; 134 } 135 }); 136 137 // Si encontramos una imagen válida, disparamos su click 138 if (selectedImg) { 139 selectedImg.click(); 140 }*/ 141 }// FIN VALIDACION DE MOVIMIENTO DE X y Y 142 },// fin touchend 143 slideChange: function () { 144 const slidesOpinion = document.querySelectorAll('.gr_wrapper_opi .swiper-slide-visible'); 145 slidesOpinion.forEach((slide, index) => { 146 slide.classList.remove('gr_slide-1_opi', 'gr_slide-2_opi', 'gr_slide-3_opi', 'gr_slide-4_opi', 'gr_slide-5_opi'); 147 switch (index) { 148 case 0: 149 slide.classList.add('gr_slide-1_opi'); 150 break; 151 case 1: 152 slide.classList.add('gr_slide-2_opi'); 153 break; 154 case 2: 155 slide.classList.add('gr_slide-3_opi'); 156 break; 157 case 3: 158 slide.classList.add('gr_slide-4_opi'); 159 break; 160 case 4: 161 slide.classList.add('gr_slide-5_opi'); 162 break; 163 default: 164 break; 165 } 166 }); 167 }, 168 }, 169 })); 170 indexSwiperOpinion.push(this.id); 171 }//FIN IF 172 });//FIN FOREACH 173 } 174 else 175 { 176 swiperOpinionIndividual = new Swiper('.gr_swiper_opi', { 177 effect: "coverflow", 178 coverflowEffect: { 179 rotate: 0, 180 stretch: 0, 181 depth: 700, 182 modifier: 1, 183 slideShadows: false, 184 }, 185 grabCursor: true, 186 navigation: { 187 nextEl: ".gr_swiper-button-next-opi", 188 prevEl: ".gr_swiper-button-prev-opi", 189 }, 190 pagination: { 191 el: ".gr_pagination_opi", 192 clickable: true, // Asegúrate de que la paginación sea clickeable 193 dynamicBullets: true, 194 }, 195 on: { 196 touchStart: function (swiper, e) { 197 //console.log('Touch start detectado', e); 198 199 // En PointerEvent, e.clientX / e.clientY están directamente disponibles 200 //XSwiper = e.clientX; 201 //YSwiper = e.clientY; 202 //TimeSwiper = Date.now(); 203 XSwiper = e.touches ? e.touches[0].clientX : e.clientX; 204 YSwiper= e.touches ? e.touches[0].clientY : e.clientY; 205 TimeSwiper = Date.now(); 206 207 208 }, 209 touchEnd: function (swiper, e) { 210 //console.log('Touch end detectado', e); 211 212 const endX = e.changedTouches ? e.changedTouches[0].clientX : e.clientX; 213 const endY = e.changedTouches ? e.changedTouches[0].clientY : e.clientY; 214 const endTime = Date.now(); 215 216 const distX = Math.abs(endX - XSwiper); 217 const distY = Math.abs(endY - YSwiper); 218 const duration = endTime - TimeSwiper; 219 220 // Si no hubo movimiento ni fue largo â TAP real 221 if (distX < 10 && distY < 10 && duration < 250) { 222 // ð¹ obtener todos los elementos bajo el punto del toque 223 const elements = document.elementsFromPoint(endX, endY); 224 225 // ð¹ filtrar slides visibles 226 const visibleSlides = elements.filter(el => 227 el.classList?.contains('swiper-slide') && 228 getComputedStyle(el).op
228acity > 0 && 229 getComputedStyle(el).pointerEvents !== 'none' 230 ); 231 232 if (!visibleSlides.length) return; 233 234 // ð¹ función auxiliar para calcular opacidad efectiva 235 function getEffectiveOpacity(el) { 236 let opacity = 1; 237 let current = el; 238 while (current && current !== document.body) { 239 const o = parseFloat(getComputedStyle(current).opacity); 240 opacity *= isNaN(o) ? 1 : o; 241 current = current.parentElement; 242 } 243 return opacity; 244 } 245 246 // ð¹ ordenar por opacidad efectiva y quedarse con el más visible 247 visibleSlides.sort((a, b) => getEffectiveOpacity(b) - getEffectiveOpacity(a)); 248 const topSlide = visibleSlides[0]; 249 250 // ð¹ buscar imagen visible dentro del slide 251 const imgs = topSlide.querySelectorAll('a'); 252 if (!imgs.length) return; 253 254 // elegir la imagen con mayor opacidad efectiva 255 const visibleImgs = Array.from(imgs) 256 .filter(img => getComputedStyle(img).display !== 'none') 257 .sort((a, b) => getEffectiveOpacity(b) - getEffectiveOpacity(a)); 258 259 const topImg = visibleImgs[0]; 260 261 if (topImg) { 262 console.log('â Tap sobre anchor visible:', topImg); 263 topImg.click(); // dispara el click de la imagen 264 } else { 265 console.log('â ï¸ No se encontró imagen visible dentro del slide.'); 266 } 267 /*const elements = document.elementsFromPoint(e.clientX, e.clientY); 268 if (!elements.length) return; 269 270 // Filtramos solo imágenes visibles 271 const images = Array.from(elements).filter(el => el.tagName === 'IMG'); 272 if (!images.length) return; 273 274 let selectedImg = null; 275 let maxOpacity = -1; 276 let minDistance = Infinity; 277 278 images.forEach(img => { 279 const effOpacity = getEffectiveOpacity(img); 280 if (effOpacity === 0) return; // saltar invisibles 281 282 // distancia al clic para desempate 283 const rect = img.getBoundingClientRect(); 284 const imgCenterX = rect.left + rect.width / 2; 285 const imgCenterY = rect.top + rect.height / 2; 286 const dx = endX - imgCenterX; 287 const dy = endY - imgCenterY; 288 const distance = Math.sqrt(dx*dx + dy*dy); 289 290 // Prioridad: mayor opacidad, luego menor distancia 291 if (effOpacity > maxOpacity || (effOpacity === maxOpacity && distance < minDistance)) { 292 maxOpacity = effOpacity; 293 minDistance = distance; 294 selectedImg = img; 295 } 296 }); 297 298 // Si encontramos una imagen válida, disparamos su click 299 if (selectedImg) { 300 selectedImg.click(); 301 }*/ 302 }// FIN VALIDACION DE MOVIMIENTO DE X y Y 303 },// fin touchend 304 slideChange: function () { 305 const slidesOpinion = document.querySelectorAll('.gr_wrapper_opi .swiper-slide-visible'); 306 slidesOpinion.forEach((slide, index) => { 307 slide.classList.remove('gr_slide-1_opi', 'gr_slide-2_opi', 'gr_slide-3_opi', 'gr_slide-4_opi', 'gr_slide-5_opi'); 308 switch (index) { 309 case 0: 310 slide.classList.add('gr_slide-1_opi'); 311 break; 312 case 1: 313 slide.classList.add('gr_slide-2_opi'); 314 break; 315 case 2: 316 slide.classList.add('gr_slide-3_opi'); 317 break; 318 case 3: 319 slide.classList.add('gr_slide-4_opi'); 320 break; 321 case 4: 322 slide.classList.add('gr_slide-5_opi'); 323 break; 324 default: 325 break; 326 } 327 }); 328 }, 329 }, 330 }); 331 } 332 // Forzar actualización después de un pequeño retraso 333 setTimeout(() => { 334 for(let i=0;i<swiperOpinion.length;i++) 335 { 336 swiperOpinion[i].updateSize(); 337 swiperOpinion[i].updateSlides(); 338 swiperOpinion[i].update(); 339 } 340 341 if (typeof(swiperOpinionInvidual)!="undefined") { 342 343 swiperOpinionInvidual.updateSize(); 344 swiperOpinionInvidual.updateSlides();
345 swiperOpinionInvidual.update(); 346 347 } 348 }, 300); // Ajusta el tiempo si es necesario 349 350} 351 352//window.addEventListener('load', () => { 353// const swiperContainer = document.querySelector('.gr_swiper_opi'); 354// if (swiperContainer) { 355// initializeSwiperOpinion(); 356// } 357//}); 358 359// Función debounce 360function debounce(func, wait) { 361 let timeout; 362 return function (...args) { 363 clearTimeout(timeout); 364 timeout = setTimeout(() => func.apply(this, args), wait); 365 }; 366} 367 368// Actualizar Swipers al redimensionar la ventana con debounce 369window.addEventListener('resize', debounce(() => { 370 if (swiperOpinion) { 371 for(let i=0;i<swiperOpinion.length;i++) 372 { 373 swiperOpinion[i].updateSize(); 374 swiperOpinion[i].updateSlides(); 375 swiperOpinion[i].update(); 376 } 377 } 378 379 if (typeof(swiperOpinionInvidual)!="undefined") { 380 381 swiperOpinionInvidual.updateSize(); 382 swiperOpinionInvidual.updateSlides(); 383 swiperOpinionInvidual.update(); 384 385 } 386}, 200)); 387 388// Actualizar Swiper al cambiar de pestaña 389document.addEventListener('visibilitychange', () => { 390 if (document.visibilityState === 'visible' && swiperOpinion) { 391 for(let i=0;i<swiperOpinion.length;i++) 392 { 393 swiperOpinion[i].update(); 394 } 395 if (typeof(swiperOpinionInvidual)!="undefined") 396 { 397 398 swiperOpinionInvidual.updateSize(); 399 swiperOpinionInvidual.updateSlides(); 400 swiperOpinionInvidual.update(); 401 402 } 403 } 404});
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.