触摸滑动轮播
触摸滑动:手机上用手指左右滑切换轮播,是移动端体验的及格线。三个触摸事件:touchstart 记起点、touchmove 跟手拖动(加视觉反馈)、touchend 判断滑动距离决定切还是回。
判定规则:松手时滑动距离超过容器宽的 20%(或 50px)就切换,否则回弹;也可以用 transform 实时跟手(touchmove 时 translate = 起点偏移),手感最佳。
- touchstart 记录 startX;touchmove 实时跟手位移
- touchend:位移 > 20% 宽度则切换,否则 transition 回弹
- PC 鼠标拖拽可用 pointerdown/move/up 统一处理
HTML
<style> #touch { max-width: 420px; margin: 20px auto; overflow: hidden; border-radius: 12px; } #touch .track { display: flex; transition: transform .35s ease; } #touch .slide { min-width: 100%; height: 160px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 18px; user-select: none; } #touch .t1 { background: #4a9eff; } #touch .t2 { background: #f778ba; } #touch .t3 { background: #57ab5a; } #touch.dragging .track { transition: none; } </style> <div id="touch"><div class="track"> <div class="slide t1">手指/鼠标拖我 →</div> <div class="slide t2">第 2 张</div> <div class="slide t3">第 3 张</div> </div></div> <script> var box = document.getElementById('touch'); var track = box.querySelector('.track'); var n = track.children.length, i = 0, startX = 0, curX = 0; function render() { track.style.transform = 'translateX(' + curX + 'px)'; } box.addEventListener('pointerdown', function (e) { startX = e.clientX - curX; box.classList.add('dragging'); box.setPointerCapture(e.pointerId); }); box.addEventListener('pointermove', function (e) { curX = e.clientX - startX; // 实时跟手 var w = box.offsetWidth; if (curX > 0) curX = curX * 0.3; // 边缘阻尼 if (curX < -(n - 1) * w) curX = -(n - 1) * w - ((-(n - 1) * w) - curX) * 0.7; render(); }); box.addEventListener('pointerup', function () { box.classList.remove('dragging'); var w = box.offsetWidth; var idx = Math.round(-curX / w); i = Math.max(0, Math.min(idx, n - 1)); // 吸附到最近一张 curX = -i * w; render(); }); render(); </script>
本节要点触摸滑动 = pointer 跟手拖动 + 松手按距离吸附;边缘阻尼防止拉过头。




