H5 js手写一个联动的轮播图
事件名 | 使用到的事件 |
---|---|
过渡事件 | transitionend |
触摸事件 | touchstart |
滑动事件 | touchmove |
离开事件 | touchend |
同一时间多次拖拽,滑动页面会导致页面无法滑动,属于正常现象,等定时器自动轮播一张图片就会恢复,(原因:新增了节流阀,防止一次划过多张图片)
// html代码
<template>
<div class="box">
<div class="swiper111">
<div class="container">
<ul
ref="imgBox11"
@transitionend="animateEnd"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
>
<li><img :src="imgList[imgList.length - 1].img" alt="" /></li>
<li v-for="(item, index) in imgList" :key="index">
<img :src="item.img" alt="" />
</li>
<li><img :src="imgList[0].img" alt="" /></li>
</ul>
</div>
</div>
<div class="swiper222">
<div class="container">
<ul
ref="imgBox22"
@transitionend="animateEnd"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
>
<li><img :src="imgList[imgList.length - 1].img" alt="" /></li>
<li v-for="(item, index) in imgList" :key="index">
<img :src="item.img" alt="" />
</li>
<li><img :src="imgList[0].img" alt="" /></li>
</ul>
</div>
</div>
</div>
</template>
js部分
<script>
export default {
name: "",
components: {},
filter: {},
mixins: {},
props: {},
data() {
return {
imgArr: [
{
img: "http://img.hb.aicdn.com/adbde61e4343dedd21e97ea7f22666825a8db7d077ffe-qn8Pjn_fw658",
},
{
img: "http://img.hb.aicdn.com/adeed7d28df6e776c2fa6032579c697381d1a82b7fe00-fwRqgn_fw658",
},
{
img: "http://img.hb.aicdn.com/ab7f48509b3c0353017d9a85ef1d12400c9b2724540d4-p3zouo_fw658",
},
{
img: "http://img.hb.aicdn.com/60f788fc2a846192f224b9e6d4904b30e54926211d3d67-ACFJ9G_fw658",
},
], // 放图片的数组
flag: true, // 节流阀 防止快速滑动
imgIndex: 0, // 当前展示图片
timer: null, // 圆点定时器
imgWidth: 0, // 图片宽度
startX: 0, // 手指开始触摸位置
moveX: 0, // 手指移动距离
interval: 2000, // 滚动间隔时间
};
},
watch: {},
computed: {
translateX() {
// 计算图片ul当前距离
return -(this.imgWidth + this.imgWidth * this.imgIndex);
},
},
created() {},
mounted() {
this.imgWidth = window.innerWidth; // 获取图片宽度
// ul先左移动一个图片距离,显示第一张图片
this.$refs.imgBox11.style.transform = `translateX(-${this.imgWidth}px)`;
this.$refs.imgBox22.style.transform = `translateX(-${this.imgWidth}px)`;
this.timer = setInterval(() => {
// 自动轮播
this.imgIndex++;
this.circleIndex++;
this.$refs.imgBox11.style.transition = "all .5s"; // 切换下一张图片
this.$refs.imgBox22.style.transition = "all .5s"; // 切换下一张图片
this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
}, this.interval);
},
updated() {},
activated() {},
destroyed() {},
methods: {
// 过渡结束事件
animateEnd() {
if (this.imgIndex >= this.imgArr.length) {
// 判断当前图片索引是否为最后一张图
this.imgIndex = 0;
this.$refs.imgBox11.style.transition = "none"; // 迅速跳转至第一张图
this.$refs.imgBox22.style.transition = "none"; // 迅速跳转至第一张图
this.$refs.imgBox11.style.transform = `translateX(-${this.imgWidth}px)`;
this.$refs.imgBox22.style.transform = `translateX(-${this.imgWidth}px)`;
}
if (this.imgIndex < 0) {
// 判断当前图片索引是否为第一张图
this.imgIndex = this.imgArr.length - 1;
this.$refs.imgBox11.style.transition = "none"; // 迅速跳转至最后一张图
this.$refs.imgBox22.style.transition = "none"; // 迅速跳转至最后一张图
this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
}
this.flag = true; // 打开节流阀
},
// 手指开始触摸事件
touchstart(event) {
clearInterval(this.timer); // 关闭自动轮播
if (this.flag) {
this.startX = event.targetTouches[0].clientX; // 获取开始触摸位置
}
},
// 手指开始移动
touchmove(event) {
if (this.flag) {
this.moveX = event.targetTouches[0].clientX - this.startX; // 手指移动位置
this.$refs.imgBox11.style.transition = "none"; // 图片ul跟随手指移动
this.$refs.imgBox22.style.transition = "none"; // 图片ul跟随手指移动
this.$refs.imgBox11.style.transform = `translateX(${
this.translateX + this.moveX
}px)`;
this.$refs.imgBox22.style.transform = `translateX(${
this.translateX + this.moveX
}px)`;
}
},
// 结束触摸
touchend(event) {
if (this.flag) {
if (this.moveX > 80) {
// 移动距离大于80,图片索引--
this.imgIndex--;
this.circleIndex--;
} else if (this.moveX < -80) {
// 移动距离小于-80,图片索引++
this.imgIndex++;
this.circleIndex++;
}
this.$refs.imgBox11.style.transition = "all .5s"; // 展示当前索引图片
this.$refs.imgBox22.style.transition = "all .5s"; // 展示当前索引图片
this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
}
// 触摸事件完成,继续自动轮播
clearInterval(this.timer); // 防止定时器叠加
this.timer = setInterval(() => {
this.imgIndex++;
this.circleIndex++;
this.$refs.imgBox11.style.transition = "all .5s";
this.$refs.imgBox22.style.transition = "all .5s";
this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
}, this.interval);
this.flag = false; // 关闭节流阀,等待动画完成
},
},
};
</script>
css样式
<style scoped lang="scss">
.box {
display: flex;
.swiper111 {
width: 100%;
height: 506px;
background-color: #39a9ed;
overflow: hidden;
position: relative;
.container {
width: 375px;
height: 100%;
display: flex;
ul {
overflow: hidden;
width: 4500px;
height: 100%;
flex-shrink: 0;
list-style-type: none;
li {
float: left;
width: 750px;
img {
width: 100%;
}
}
}
}
.circle {
position: absolute;
// position: relative;
justify-content: center;
ol {
display: flex;
bottom: 5px;
right: 5px;
margin: 0;
li {
display: inline-block;
width: 20px;
height: 20px;
margin-left: 20px;
background-color: red;
list-style: none;
border-radius: 10px;
transition: all 0.3s;
.current {
width: 15px;
}
}
}
}
}
.swiper222 {
width: 100%;
height: 600px;
background-color: #39a9ed;
overflow: hidden;
position: relative;
.container {
width: 375px;
height: 100%;
display: flex;
ul {
overflow: hidden;
width: 4500px;
height: 100%;
flex-shrink: 0;
list-style-type: none;
li {
float: left;
width: 750px;
img {
width: 100%;
}
}
}
}
}
}
</style>