PageSourceSearch

https://www.santanderconsumer.es/Content/assets/src/js/modules/sliderPrestamos.js

js santanderconsumer.es collected 2026-09-24 09:44:37 UTC 4,645 bytes, 144 lines download raw bytes

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.