原生JS实现移动端轮播图滑动切换详解
本文详细解析使用原生JavaScript实现移动端轮播图的核心逻辑,涵盖自动播放、无缝切换及分页器同步。重点讲解touchstart、touchmove和touchend手势事件的配合使用,通过计算滑动距离与屏幕宽度的比例(1/3阈值)判断是否切换图片,并结合CSS3过渡动画实现流畅的滑动体验。
移动端轮播图实现概述
本文分享了一段使用JavaScript实现的移动端轮播图滑动切换代码,供读者参考学习。
在移动端实现轮播效果,核心在于处理用户的手势交互。
轮播图功能需求分析
接下来对轮播图的功能需求进行具体分析。
实现一个完整的轮播图需要满足以下六个条件: 1. 支持自动轮播且实现无缝循环,需结合定时器与过渡动画。 2. 分页指示器(小圆点)需随图片切换同步更新,通常根据当前索引进行状态切换。 3. 支持用户手指滑动效果,依赖移动端touch事件监听。 4. 图片切换时,分页指示器需同步变化。 5. 滑动结束时,若滑动距离未超过屏幕宽度的1/3,图片应通过过渡动画恢复原位。 6. 滑动结束时,若滑动距离超过屏幕宽度的1/3,则根据滑动方向切换至下一张图片,并应用过渡动画。
HTML页面结构搭建
以下是HTML页面的基本结构搭建。
<!--轮播图-->
<div class="jd_banner">
<ul class="clearfix">
<li><a href="#" ><img src="images/l8.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l1.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l2.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l3.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l4.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l5.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l6.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l7.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l8.jpg" alt=""></a></li>
<li><a href="#" ><img src="images/l1.jpg" alt=""></a></li>
</ul>
<ul class="clearfix">
<li class="now"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
JavaScript核心逻辑实现
接下来是核心的JavaScript逻辑实现部分。
/* 动态设置过渡 */
var addTransition = function (ele) {
ele.style.transition = "all .6s";
ele.style.webkitTransition = "all .6s";
};
/* 移除过渡效果 */
var removeTransition = function (ele) {
ele.style.transition = "none";
ele.style.webkitTransition = "none";
};
/* 设置容器平移 -- 也就是滑动动画
ele:当前元素
xwidth:平移的距离
*/
var setTranslateX = function (ele, xwidth) {
ele.style.transform = "translateX(" + xwidth + "px)";
ele.style.webkitTransform = "translateX(" + xwidth + "px)";
}
var banner = function () {
/** 轮播图分析 */
/** 1 自动轮播且无缝 [定时器、过渡动画]
* 2 点要随着图片的轮播而改变 [根据索引切换]
* 3 滑动效果 [touch事件]
* 4 图片随着点而变化
* 5 滑动结束的时候,如果滑动的距离不超过屏幕的1/3,就恢复回去 [过渡]
* 6 滑动结束的时候,如果滑动的距离超过屏幕的1/3,就切换 [滑动方向 + 过渡]]
*/
var timer = ''
/* 封装定时器函数 */
var startInterval = function () {
timer = setInterval(function () {
index++;// 基于索引 做位移
addTransition(imgBox); // 为轮播图片组的ul设置过渡函数
setTranslateX(imgBox, -index * width);// 根据当前索引值计算平移的距离
}, 2000);
}
var banner = document.querySelector(".jd_banner");
var width = banner.offsetWidth; // 屏幕的宽度
var imgBox = banner.querySelector("ul:first-child"); // 轮播图片ul
var length = imgBox.querySelectorAll("li").length; // 图片的个数
var pointBox = banner.querySelector("ul:last-child");// 分页器ul
var points = pointBox.querySelectorAll("li");// 分页器集合
var index = 1; // 初始化索引,由于要无缝衔接,索引从1开始
startInterval();
/* transitionend事件:当元素过渡动画结束后执行
每次轮播动画结束后,判断当前索引值
*/
imgBox.addEventListener("transitionend", function () {
if (index >= length - 1) {
index = 1;
// 清过渡,瞬间定位imgBox
removeTransition(imgBox);
setTranslateX(imgBox, -index * width);
}
// 滑动的时候也需要无缝
else if (index <= 0) {
index = 8;
removeTransition(imgBox);
setTranslateX(imgBox, -index * width);
}
showPoint(index - 1); // 改变分页器状态
});
var showPoint = function (index) {
for (var i = 0; i < points.length; i++) {
points[i].className = '';
}
points[index].className = "now";
};
/* 滑动切换 (touch事件) */
var startX = 0; // 触摸起始点
imgBox.addEventListener("touchstart", function (e) {
// 记录起始位置的X坐标
clearInterval(timer);
startX = e.touches[0].clientX;
});
var distanceX = 0;
var translateX = 0;
// **** 加一个标识,判断用户有没有滑动
var isMove = false
imgBox.addEventListener("touchmove", function (e) {
var moveX = e.touches[0].clientX;
// 计算位移,有正负方向
distanceX = moveX - startX;
// 计算目标元素的位移
// 元素将要的定位 = 当前定位 + 手指移动的距离
translateX = -index * width + distanceX;
// ********** 要想图片实时地跟着手指走,一定要把过渡清楚掉
removeTransition(imgBox)
setTranslateX(imgBox, translateX);
isMove = true;// 确定用户有滑动
e.preventDefault(); // 去除移动端浏览器默认的滑动事件
});
imgBox.addEventListener("touchend", function (e) {
if (isMove) {
if (Math.abs(distanceX) > width / 3) {
// 切换
if (distanceX > 0) {
// 上一张
index = index - 1;
} else {
// 下一张
index = index + 1;
}
addTransition(imgBox); // 设置过渡动画
setTranslateX(imgBox, -index * width);
if (index >= 9) {
index = 1;
}
if (index <= 0) {
index = 8;
}
showPoint(index - 1);
} else {
// 不满足滑动条件,回退到之前的状态
addTransition(imgBox);
setTranslateX(imgBox, -index * width);
showPoint(index - 1);
}
}
// **** 最好做一次参数的重置
startX = 0;
distanceX = 0;
isMove = false;
// ****** 为了严谨,再清一次定时器
clearInterval(timer)
// 加上定时器
startInterval();
});
};
总结与插件建议
最后对实现过程进行总结。
使用原生JavaScript实现滑动切换的核心原理,主要依赖于移动端的手势事件机制。
- touchstart:当手指触摸屏幕时触发该事件。
- touchmove:当手指在屏幕上滑动时持续触发该事件。
- touchend:当手指离开屏幕时触发该事件。
通过组合使用touch相关事件,可以实现移动端常见的滑动交互效果。
知名轮播插件Swiper的底层实现原理也基于此机制,因此为了提升开发效率,在实际项目中推荐使用成熟的Swiper插件。
以上内容为本文的全部讲解,希望能为读者的学习提供有益帮助,也欢迎大家继续支持本站获取更多技术资源。
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
