技术选型避坑指南与实战经验总结
先看效果,再看代码
最近接手了一个移动端项目,需求很简单:实现一个可以左右滑动切换页面的功能。一开始我觉得这不就是个普通的 touch 事件吗?结果真写起来才发现事情没那么简单。
直接上核心代码:
let startX = 0;
let moveX = 0;
let distance = 0;
document.querySelector('.slider').addEventListener('touchstart', (e) => {
startX = e.touches[0].pageX;
});
document.querySelector('.slider').addEventListener('touchmove', (e) => {
moveX = e.touches[0].pageX;
distance = moveX - startX;
// 实时更新位置
document.querySelector('.slider').style.transform = translateX(${distance}px);
});
document.querySelector('.slider').addEventListener('touchend', () => {
if (Math.abs(distance) > 100) {
// 判断滑动距离,执行页面切换
document.querySelector('.slider').style.transition = 'transform 0.3s ease';
document.querySelector('.slider').style.transform = translateX(-100%);
} else {
// 恢复原位
document.querySelector('.slider').style.transform = 'translateX(0)';
}
});
这段代码亲测有效,基本能满足大部分场景的需求。但说实话,这里面有不少坑点需要注意,后面我会详细说说。
这个场景最好用
在实际开发中,我主要遇到三种常见的技术选型方案:
- 纯手写 touch 事件:就像上面的代码一样,自己监听 touchstart、touchmove 和 touchend。适合对性能要求高、需要完全自定义的场景。
- 使用第三方库:比如 swiper.js 这种专门处理滑动的库。适合快速开发、功能需求复杂的项目。
- CSS scroll-snap:通过 CSS 的 scroll-snap-type 和 scroll-snap-align 属性来实现。适合简单的滑动效果。
我个人更倾向于第一种方式,虽然写起来稍微麻烦一点,但可控性最强,尤其是当需求频繁变动的时候,不用被第三方库的限制束缚住。
踩坑提醒:这三点一定注意
在写这段代码的过程中,我至少踩了三个大坑,这里分享给大家:
1. 阻止默认行为的问题
在移动端,touchmove 默认会触发页面滚动。如果你不想让页面跟着滑动,记得在 touchmove 事件里加上 preventDefault:
document.querySelector('.slider').addEventListener('touchmove', (e) => {
e.preventDefault();
moveX = e.touches[0].pageX;
distance = moveX - startX;
document.querySelector('.slider').style.transform = translateX(${distance}px);
}, { passive: false });
这里特别要注意的是,现代浏览器为了性能优化,默认会让 touch 事件变成 passive(无法阻止默认行为)。所以必须显式设置 { passive: false },不然 preventDefault 会失效。
2. 滑动灵敏度的调整
一开始我把滑动的判断阈值设成了 50px,结果发现用户稍微一划就切页了,体验很差。后来改成 100px 才感觉刚刚好。这个数值可以根据实际项目需求调整,但建议不要低于 80px。
3. 动画结束后的状态重置
滑动结束后,一定要记得把 transform 和 transition 样式都重置,否则会影响下一次滑动的效果。正确的做法是:
document.querySelector('.slider').style.transition = '';
document.querySelector('.slider').style.transform = '';
高级技巧:加点小细节提升体验
为了让滑动效果更加流畅和自然,我加了几个小改进:
1. 动态计算滑动速度
有时候用户滑得很快,这时候即使滑动距离没达到阈值,也应该触发页面切换。可以通过记录 touchstart 和 touchend 的时间差来计算速度:
let startTime = 0;
let endTime = 0;
document.querySelector('.slider').addEventListener('touchstart', (e) => {
startX = e.touches[0].pageX;
startTime = Date.now();
});
document.querySelector('.slider').addEventListener('touchend', () => {
endTime = Date.now();
let duration = endTime - startTime;
let speed = Math.abs(distance) / duration;
if (speed > 0.3 || Math.abs(distance) > 100) {
// 如果速度够快或者滑动距离够长,就切换页面
document.querySelector('.slider').style.transition = 'transform 0.3s ease';
document.querySelector('.slider').style.transform = translateX(-100%);
} else {
document.querySelector('.slider').style.transform = 'translateX(0)';
}
});
2. 增加边界检测
如果用户滑到最后一页还继续滑,应该有边界回弹的效果。可以在滑动开始前检查当前页面索引:
if (currentIndex === 0 && distance > 0) {
// 第一页,不允许再往右滑
return;
}
if (currentIndex === totalPages - 1 && distance < 0) {
// 最后一页,不允许再往左滑
return;
}
拓展用法还有很多
以上是我个人对这个移动端滑动功能的完整讲解,实际上还有不少可以优化的地方。比如:
- 支持竖向滑动
- 增加分页指示器
- 适配不同屏幕尺寸
这个技巧的拓展用法还有很多,后续会继续分享这类博客。如果有更优的实现方式,欢迎评论区交流!

暂无评论