1export function initSliderPrestamos() { 2 const root = document.querySelector('.sc-main-slider-prestamos'); 3 if (!root) return; 4 5 const track = root.querySelector('.sc-slider-prestamos'); 6 const items = [...track.querySelectorAll('.sc-item-prestamos')]; 7 const prevBtn = root.querySelector('.sc-prev'); 8 const nextBtn = root.querySelector('.sc-next'); 9 10 if (!items.length || !prevBtn || !nextBtn) return; 11 12 let index = 0; // Ãndice âvirtualâ por tarjeta 13 let step = 0; // ancho 1 tarjeta + gap real 14 let maxIndex = 0; // Ãndice máximo permitido 15 let viewport = root.clientWidth; 16 let startX = 0, 17 startT = 0, 18 startTx = 0; 19 let tx = 0; // translateX actual (negativo hacia la izda) 20 const EASE_MS = 350; 21 22 // Hace focusable para teclado 23 root.setAttribute('tabindex', '0'); 24 25 function getStep() { 26 // Distancia real entre item 0 y 1 (incluye gap de flex) 27 if (items.length < 2) return items[0].offsetWidth; 28 return items[1].offsetLeft - items[0].offsetLeft; 29 } 30 31 function compute() { 32 viewport = root.clientWidth; 33 step = getStep(); 34 35 const totalWidth = items.at(-1).offsetLeft + items.at(-1).offsetWidth; 36 const maxScroll = Math.max(0, totalWidth - viewport); 37 38 // desactivar slider (desktop) 39 const fits = totalWidth <= viewport + 1; 40 root.dataset.disabled = fits ? 'true' : 'false'; 41 track.style.transform = 'translateX(0px)'; 42 index = 0; 43 tx = 0; 44 45 // Máximo pasos 46 maxIndex = Math.max(0, Math.ceil(maxScroll / step)); 47 updateButtons(); 48 } 49 50 function snapTo(i) { 51 index = Math.max(0, Math.min(maxIndex, i)); 52 tx = -index * step; 53 track.style.transition = `transform ${EASE_MS}ms ease`; 54 track.style.transform = `translateX(${tx}px)`; 55 updateButtons(); 56 // Limpia la transición 57 window.setTimeout(() => { 58 track.style.transition = ''; 59 }, EASE_MS); 60 } 61 62 function updateButtons() { 63 const disabled = root.dataset.disabled === 'true'; 64 const atStart = index <= 0 || disabled; 65 const atEnd = index >= maxIndex || disabled; 66 67 prevBtn.classList.toggle('sc-disabled', atStart); 68 nextBtn.classList.toggle('sc-disabled', atEnd); 69 prevBtn.setAttribute('aria-disabled', String(atStart)); 70 nextBtn.setAttribute('aria-disabled', String(atEnd)); 71 } 72 73 // Click flechas 74 prevBtn.addEventListener('click', () => { 75 if (root.dataset.disabled === 'true') return; 76 snapTo(index - 1); 77 }); 78 nextBtn.addEventListener('click', () => { 79 if (root.dataset.disabled === 'true') return; 80 snapTo(index + 1); 81 }); 82 83 // Teclado 84 root.addEventListener('keydown', (e) => { 85 if (root.dataset.disabled === 'true') return; 86 if (e.key === 'ArrowRight') { 87 e.preventDefault(); 88 snapTo(index + 1); 89 } 90 if (e.key === 'ArrowLeft') { 91 e.preventDefault(); 92 snapTo(index - 1); 93 } 94 }); 95 96 // Swipe táctil 97 function onPointerDown(e) { 98 if (root.dataset.disabled === 'true') return; 99 const isTouch = e.type.startsWith('touch'); 100 startX = isTouch ? e.touches[0].clientX : e.clientX; 101 startT = performance.now(); 102 startTx = tx; 103 track.style.transition = ''; 104 window.addEventListener(isTouch ? 'touchmove' : 'pointermove', onPointerMove, { passive: true }); 105 window.addEventListener(isTouch ? 'touchend' : 'pointerup', onPointerUp, { once: true }); 106 } 107 108 function onPointerMove(e) { 109 const x = e.touches ? e.touches[0].clientX : e.clientX; 110 const dx = x - startX; 111 const totalWidth = items.at(-1).offsetLeft + items.at(-1).offsetWidth; 112 const maxScroll = Math.max(0, totalWidth - viewport); 113 tx = Math.min(0, Math.max(-maxScroll, startTx + dx)); 114 track.style.transform = `translateX(${tx}px)`; 115 } 116 117 function onPointerUp(e) { 118 const endX = e.changedTouches ? e.changedTouches[0].clientX : e.clientX; 119 const dx = endX - startX; 120 const dt = Math.max(1, performance.now() - startT); 121 const velocity = dx / dt; 122 123 if (Math.abs(dx) > step * 0.25 || Math.abs(velocity) > 0.5) { 124 const dir = dx < 0 ? 1 : -1; 125 snapTo(index + dir); 126 } else { 127 const approx = Math.round(Math.abs(tx) / step); 128 snapTo(approx); 129 } 130 131 window.removeEventListener('pointermove', onPointerMove); 132 window.removeEventListener('touchmove', onPointerMove); 133 } 134 135 // Soporte pointer/touch 136 track.addEventListener('pointerdown', onPointerDown);
137 track.addEventListener('touchstart', onPointerDown, { passive: true }); 138 139 window.addEventListener('resize', () => { 140 compute(); 141 }); 142 143 compute(); 144}
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.