先上代码
原先使用DOM写的,转到vue暂时没去更改成ref
整体的效果实现,通过更改margin来显示切换图片的样式
<template>
<div class="imgs">
<div class="img" style="" v-for="(e, i) in imgUrl" :key="i">
<img :src="https://juejin.cn/post/e" />
</div>
<div class="img">
<img :src="https://juejin.cn/post/imgUrl[0]" />
</div>
<div class="btn-left" @click="btn_left"></div>
<div class="btn-right" @click="btn_right"></div>
<ul>
<li @click="bt(i)" v-for="(e,i) in 6" :key="i"></li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
r: true,
ind: 0,
imgs: document.getElementsByClassName("img"),
};
},
props: ["imgUrl"],
methods: {
bt(e) {
if (e !== this.ind) {
if (e > this.ind) {
let o = e - this.ind;
console.log(o)
for (let i = 0; i < o; i++) {
this.imgs[this.ind].style.transition = ".5s";
this.imgs[this.ind].style.marginLeft = "-500px";
this.ind++;
}
}
if (e < this.ind) {
console.log('object')
let o = this.ind - e;
for (let i = 0; i < o; i++) {
this.imgs[this.ind - 1].style.transition = ".5s";
this.imgs[this.ind - 1].style.marginLeft = "0";
this.ind--;
}
}
}
},
btn_left() {
if (this.r) {
this.r = false;
setTimeout(() => {
this.r = true;
}, 1000);
if (this.ind === 0) {
for (let i = 0; i < this.imgs.length - 1; i++) {
this.imgs[i].style.transition = "none";
this.imgs[i].style.marginLeft = "-500px";
}
this.ind = this.imgs.length - 1;
setTimeout(() => {
this.imgs[this.ind - 1].style.transition = ".5s";
this.imgs[this.ind - 1].style.marginLeft = "0";
this.ind--;
}, 100);
} else {
this.imgs[this.ind - 1].style.transition = ".5s";
this.imgs[this.ind - 1].style.marginLeft = "0";
this.ind--;
}
}
},
btn_right() {
if (this.r) {
this.r = false;
setTimeout(() => {
this.r = true;
}, 1000);
this.imgs[this.ind].style.transition = ".5s";
this.imgs[this.ind].style.marginLeft = "-500px";
this.ind++;
if (this.ind == this.imgs.length - 1) {
setTimeout(() => {
for (let i = 0; i < this.ind; i++) {
this.imgs[i].style.transition = "none";
this.imgs[i].style.marginLeft = "0px";
}
this.ind = 0;
}, 600);
}
}
},
},
computed: {},
};
</script>
<style scoped>
ul {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
flex-direction: row;
justify-content: center;
}
li {
z-index: 101;
width: 20px;
font-size: 40px;
}
img {
width: 500px;
height: 300px;
}
.imgs {
height: 300px;
position: relative;
margin: 0 auto;
overflow: hidden;
display: flex;
flex-direction: row;
width: 500px;
}
.btn-left {
position: absolute;
top: 50%;
left: 10px;
border: 10px solid transparent;
border-right: 20px solid #f00;
width: 0;
height: 0px;
}
.btn-right {
position: absolute;
top: 50%;
right: 10px;
border: 10px solid transparent;
border-left: 20px solid #f00;
width: 0;
height: 0px;
}
</style>
复制代码
元素部分
imgs:代表父节点
img:每张图片
btn_left:左按钮
btn_right:右边按钮
ul > li:小圆点,可以设置成imgUrl.length
在样式中需要多放一张图片,实现最后一张图的无缝切换
<div class="imgs">
<div class="img" style v-for="(e, i) in imgUrl" :key="i">
<img :src="e" />
</div>
<div class="img">
<img :src="imgUrl[0]" />
</div>
<div class="btn-left" @click="btn_left"></div>
<div class="btn-right" @click="btn_right"></div>
<ul>
<li @click="bt(i)" v-for="(e,i) in 6" :key="i"></li>
</ul>
</div>
复制代码
整体样式采用相对定位,通过固定宽度overflow: hidden
达到效果
ul {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
flex-direction: row;
justify-content: center;
}
li {
z-index: 101;
width: 20px;
font-size: 40px;
}
img {
width: 500px;
height: 300px;
}
.imgs {
height: 300px;
position: relative;
margin: 0 auto;
overflow: hidden;
display: flex;
flex-direction: row;
width: 500px;
}
.btn-left {
position: absolute;
top: 50%;
left: 10px;
border: 10px solid transparent;
border-right: 20px solid #f00;
width: 0;
height: 0px;
}
.btn-right {
position: absolute;
top: 50%;
right: 10px;
border: 10px solid transparent;
border-left: 20px solid #f00;
width: 0;
height: 0px;
}
复制代码
js实现
变量
ind:是现在的图片下标
imgs:获取所有图片的节点
r:节流开关
imgUrl:则是传入的图片地址
方法
bt():小圆点通过传入不同值来判断需要切换到第几章图片。
btn_left():往左边切换需要知道当前是不是第一张图,如果是第一张图则关闭动画,先切换到最后一张图片,然后开启动画,从最后一张切换到倒数第二张。
btn_rigth():往右切换的时候,只需要判断是否是最后一张,如果是最后一章则和向左切换最后一张的实现方法差不多。
两个点击按钮需要实现节流,防止用户多次点击,造成最后一张图片的空白。
两个按钮每次点击,向右需要将ind++
向左则ind--
,是为了确定当前图片是第几章。
因为,最后一张图片和第一张是相同的,实现的方式是让动画暂停,从最后一张回到第一张。
切换的很快,用户无法察觉效果以及完成。
快速切换使用的是for循环,通过给每一张添加marginLeft和marginLeft归零的方式进行,循环中length-1
是因为,图片本来就是多一张用来无差别切换的。
圆点则是判断和当前位置相差几张,就循环几次添加。
export default {
data() {
return {
r: true,
ind: 0,
imgs: document.getElementsByClassName("img"),
};
},
props: ["imgUrl"],
methods: {
bt(e) {
if (e !== this.ind) {
if (e > this.ind) {
let o = e - this.ind;
console.log(o)
for (let i = 0; i < o; i++) {
this.imgs[this.ind].style.transition = ".5s";
this.imgs[this.ind].style.marginLeft = "-500px";
this.ind++;
}
}
if (e < this.ind) {
console.log('object')
let o = this.ind - e;
for (let i = 0; i < o; i++) {
this.imgs[this.ind - 1].style.transition = ".5s";
this.imgs[this.ind - 1].style.marginLeft = "0";
this.ind--;
}
}
}
},
btn_left() {
if (this.r) {
this.r = false;
setTimeout(() => {
this.r = true;
}, 1000);
if (this.ind === 0) {
for (let i = 0; i < this.imgs.length - 1; i++) {
this.imgs[i].style.transition = "none";
this.imgs[i].style.marginLeft = "-500px";
}
this.ind = this.imgs.length - 1;
setTimeout(() => {
this.imgs[this.ind - 1].style.transition = ".5s";
this.imgs[this.ind - 1].style.marginLeft = "0";
this.ind--;
}, 100);
} else {
this.imgs[this.ind - 1].style.transition = ".5s";
this.imgs[this.ind - 1].style.marginLeft = "0";
this.ind--;
}
}
},
btn_right() {
if (this.r) {
this.r = false;
setTimeout(() => {
this.r = true;
}, 1000);
this.imgs[this.ind].style.transition = ".5s";
this.imgs[this.ind].style.marginLeft = "-500px";
this.ind++;
if (this.ind == this.imgs.length - 1) {
setTimeout(() => {
for (let i = 0; i < this.ind; i++) {
this.imgs[i].style.transition = "none";
this.imgs[i].style.marginLeft = "0px";
}
this.ind = 0;
}, 600);
}
}
},
},
};
复制代码
轮播图实现的方法还有一种,通过单张图片的视口,然后所有图片拼成一张来回拉扯,但最后一张图片的实现大相径同,都是通过关闭动画时间实现的。
不喜勿喷,有想法可以提。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END