1(function() { 2 const modal = document.getElementById('account-modal'); 3 const toggle = document.querySelector('.site-navigation-toggle-holder'); 4 5 if (!modal || !toggle) return; 6 7 // Estado visible 8 const isMenuOpen = () => toggle.classList.contains('elementor-active'); 9 const isModalOpen = () => modal.classList.contains('open'); 10 11 function showModal() { 12 console.log('[MODAL] Pedido para abrir modal'); 13 if (isMenuOpen()) { 14 console.log('[MODAL] Menú estaba abierto â forzamos cierre'); 15 16 // Forzar cierre del menú removiendo clases activas 17 document.body.classList.remove('elementor-nav-menu--toggle-active'); 18 toggle.classList.remove('elementor-active'); 19 20 // Esperar el próximo ciclo para asegurarnos que el layout se actualice 21 requestAnimationFrame(() => { 22 modal.classList.add('open'); 23 console.log('[MODAL] Modal abierto después de cerrar menú'); 24 requestAnimationFrame(recalcAccountModal); 25 }); 26 27 } else { 28 modal.classList.add('open'); 29 console.log('[MODAL] Modal abierto directamente'); 30 requestAnimationFrame(recalcAccountModal); 31 } 32 } 33 34 35 function hideModal() { 36 console.log('[MODAL] Cerrando modal'); 37 modal.classList.remove('open'); 38 } 39 40 // Observa el toggle hasta que el menú esté cerrado 41 function waitForMenuClose(callback) { 42 const observer = new MutationObserver(() => { 43 if (!isMenuOpen()) { 44 observer.disconnect(); 45 callback(); 46 } 47 }); 48 observer.observe(toggle, { attributes: true, attributeFilter: ['class'] }); 49 } 50 51 // Click en el botón "Mi Cuenta" 52 document.addEventListener('click', function (e) { 53 const trigger = e.target.closest('#open-account-modal'); 54 if (trigger) { 55 e.preventDefault(); 56 e.stopPropagation(); 57 showModal(); 58 } 59 }); 60 61 // Click en backdrop o cruz 62 modal.addEventListener('click', function (e) { 63 if (e.target.matches('.account-modal__close, .account-modal__backdrop')) { 64 e.preventDefault(); 65 hideModal(); 66 } 67 }); 68 69 // Click en botón del menú 70 toggle.addEventListener('click', () => { 71 console.log('[MENU] Click en toggle'); 72 waitForMenuOpen(() => { 73 console.log('[MENU] Se detectó menú abierto'); 74 if (isModalOpen()) { 75 console.log('[MENU] Modal estaba abierto â lo cerramos'); 76 hideModal(); 77 }
78 recalcPrimary(); 79 }); 80 }); 81 82 // Observa hasta que el menú se abra 83 function waitForMenuOpen(callback) { 84 const observer = new MutationObserver(() => { 85 if (isMenuOpen()) { 86 observer.disconnect(); 87 callback(); 88 } 89 }); 90 observer.observe(toggle, { attributes: true, attributeFilter: ['class'] }); 91 } 92 93 /* ===================================================================== 94 * 1) syncDistance â mantiene ancho sin desfase 95 * ===================================================================== */ 96 function syncDistance({ source, target, from = 'left', debounceTime = 100 }) { 97 const srcEl = document.querySelector(source); 98 const tgtEl = document.querySelector(target); 99 if (!srcEl || !tgtEl) { 100 console.warn('syncDistance: source o target no encontrado', { source, target }); 101 return () => {}; 102 } 103 104 function applyDistance() { 105 const rect = srcEl.getBoundingClientRect(); 106 let width; 107 108 if (from === 'left') { 109 width = Math.ceil(rect.right); 110 } else if (from === 'right') { 111 width = Math.ceil(window.innerWidth - rect.left); 112 } else { 113 console.warn('syncDistance: valor "from" no válido:', from); 114 return; 115 } 116 117 tgtEl.style.width = `${width}px`; 118 } 119 120 // â inicial 121 (document.readyState === 'loading') 122 ? document.addEventListener('DOMContentLoaded', applyDistance) 123 : applyDistance(); 124 125 // â resize debounce 126 let id; 127 window.addEventListener('resize', () => { 128 clearTimeout(id); 129 id = setTimeout(applyDistance, debounceTime); 130 }); 131 132 return applyDistance; 133 } 134 135 /* Llamadas de arranque âââââââââââââââââââââââââââââââââââââââââââââââ */ 136 const recalcPrimary = syncDistance({ 137 source: '.site-navigation-toggle-holder', 138 target: '.site-navigation-dropdown .mobile-dd-wrapper', 139 debounceTime: 20 140 }); 141 142 const recalcAccountModal = syncDistance({ 143 source: '.header-inner .menu-secundario', 144 target: '.account-modal', 145 from: 'right', 146 debounceTime: 20 147 }); 148 // seccion con diseño overflow 149 // Función principal: recorre cada contenedor y ajusta márgenes de los hijos overflow 150 function adjustOverflow() { 151 const isMobile = window.innerWidth <= 768; 152 153 document.querySelectorAll('.contenedor-para-overflow').forEach(parent => { 154 const leftEls = parent.querySelectorAll('.overflow-contenedor.left'); 155 const rightEls = parent.querySelectorAll('.overflow-contenedor.right'); 156 157 if (isMobile) { 158 // En mobile, remover márgenes en lÃnea 159 leftEls.forEach(el => { 160 el.style.marginLeft = ''; 161 el.style.opacity = '1'; 162 }); 163 rightEls.forEach(el => { 164 el.style.marginRight = ''; 165 el.style.opacity = '1'; 166 }); 167 return; // no hacer nada más 168 } 169 170 const rect = parent.getBoundingClientRect(); 171 const style = getComputedStyle(parent); 172 const paddingLeft = parseFloat(style.paddingLeft) || 0; 173 const paddingRight = parseFloat(style.paddingRight) || 0; 174 175 // Borde interior del contenedor 176 const contentLeft = rect.left + paddingLeft; 177 const contentRight = rect.right - paddingRight; 178 179 // Distancias al viewport (clamp ⥠0) 180 const gapLeft = Math.max(contentLeft, 0); 181 const gapRight = Math.max(window.innerWidth - contentRight, 0); 182 183 // LÃmite de desbordamiento de 100px 184 const overflowLeft = Math.min(gapLeft, 200); 185 const overflowRight = Math.min(gapRight, 200); 186 187 // Aplicar margin-left negativo a los .overflow-contenedor.left 188 parent.querySelectorAll('.overflow-contenedor.left').forEach(el => { 189 el.style.marginLeft = `${-overflowLeft}px`; 190 el.style.opacity = 1; 191 }); 192 193 // Aplicar margin-right negativo a los .overflow-contenedor.right 194 parent.querySelectorAll('.overflow-contenedor.right').forEach(el => { 195 el.style.marginRight = `${-overflowRight}px`; 196 el.style.opacity = 1; 197 }); 198 });
199 } 200 201 // Debounce para resize 202 let resizeTimer; 203 window.addEventListener('DOMContentLoaded', adjustOverflow); 204 window.addEventListener('load', adjustOverflow); 205 window.addEventListener('resize', () => { 206 clearTimeout(resizeTimer); 207 resizeTimer = setTimeout(adjustOverflow, 100); 208 }); 209 210 // btn ir arriba 211 212 document.addEventListener('DOMContentLoaded', function() { 213 var goToTopButton = document.getElementById('go-to-top'); 214 215 if (goToTopButton) { 216 goToTopButton.addEventListener('click', function() { 217 window.scrollTo({ 218 top: 0, 219 behavior: 'smooth' 220 }); 221 }); 222 } 223 }); 224 225 // 1) Delegamos el click para ABRIR el modal 226 document.addEventListener('click', function(e){ 227 // si clickeo en el enlace (o en un hijo) con id open-account-modal 228 if (e.target.closest('#open-account-modal')) { 229 e.preventDefault(); 230 showModal(); 231 } 232 }); 233 234 // 2) Delegamos el click DENTRO del modal para CERRARlo 235 modal.addEventListener('click', function(e){ 236 // si clickeo en la cruz o en el backdrop 237 if (e.target.matches('.account-modal__close, .account-modal__backdrop')) { 238 e.preventDefault(); 239 hideModal(); 240 } 241 }); 242 243 // 3) Delegamos el click para el toggle de pestañas 244 modal.addEventListener('click', function(e) { 245 // 1) Busca el elemento más cercano con el atributo data-tab 246 var tabEl = e.target.closest('.account-modal__panels [data-tab]'); 247 if (!tabEl) return; 248 249 250 // 2) Desactivamos todas las âpestañasâ clickeables 251 modal.querySelectorAll('.account-modal__panels [data-tab]') 252 .forEach(el => el.classList.remove('active')); 253 // y ocultamos todos los paneles 254 modal.querySelectorAll('.tab-panel') 255 .forEach(p => p.style.display = 'none'); 256 257 // 3) Activamos el que clickeaste 258 tabEl.classList.add('active'); 259 260 // y mostramos su panel correspondiente 261 var panel = modal.querySelector('#tab-' + tabEl.dataset.tab); 262 if (panel) panel.style.display = 'block'; 263}); 264 265 266})();
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.