Vue 实现无缝滚动轮播图:带按钮控制、鼠标悬停暂停
<template>
<div class='carousel'>
<div class='carousel-wrap' :style='wrapStyle'>
<div class='carousel-item' v-for='(item, index) in items' :key='index'>
<img :src='item.src' alt=''>
</div>
</div>
<div class='carousel-control'>
<button class='carousel-prev' @click='handlePrev'><</button>
<button class='carousel-next' @click='handleNext'>></button>
</div>
</div>
</template>
<style>
.carousel {
width: 100%;
position: relative;
overflow: hidden;
}
.carousel-wrap {
display: flex;
width: 300%;
transition: transform 0.5s ease;
}
.carousel-item {
flex: 1;
margin-right: 10px;
}
.carousel-item img {
width: 100%;
}
.carousel-control {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
.carousel-prev,
.carousel-next {
width: 40px;
height: 40px;
border: none;
outline: none;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
font-size: 24px;
cursor: pointer;
opacity: 0.5;
transition: opacity 0.3s ease;
}
.carousel-prev:hover,
.carousel-next:hover {
opacity: 1;
}
</style>
<script>
export default {
data() {
return {
items: [
{ src: 'http://placehold.it/400x200/ff0000' },
{ src: 'http://placehold.it/400x200/00ff00' },
{ src: 'http://placehold.it/400x200/0000ff' },
{ src: 'http://placehold.it/400x200/ffff00' },
{ src: 'http://placehold.it/400x200/00ffff' },
{ src: 'http://placehold.it/400x200/ff00ff' }
],
currentIndex: 0,
timer: null,
isPaused: false
}
},
computed: {
wrapStyle() {
return {
transform: `translateX(-${this.currentIndex * 100}%)`
}
}
},
mounted() {
this.startTimer()
},
methods: {
startTimer() {
this.timer = setInterval(() => {
if (!this.isPaused) {
this.handleNext()
}
}, 3000)
},
handlePrev() {
this.currentIndex = (this.currentIndex - 1 + this.items.length) % this.items.length
},
handleNext() {
this.currentIndex = (this.currentIndex + 1) % this.items.length
}
},
watch: {
currentIndex(newIndex) {
if (newIndex === 0) {
setTimeout(() => {
this.currentIndex = this.items.length - 1
}, 500)
} else if (newIndex === this.items.length - 1) {
setTimeout(() => {
this.currentIndex = 0
}, 500)
}
}
}
}
</script>
<p>在这个示例中,轮播图的每个图片都用一个对象来表示,包含图片的 URL 地址等信息。轮播图的核心是通过 CSS 的 <code>transform</code> 属性实现滚动,每次滚动的距离是当前图片宽度的百分比,因此 CSS 样式中需要设置 <code>carousel-wrap</code> 元素的宽度为所有图片宽度的三倍。</p>
<p>定时滚动功能通过 <code>setInterval</code> 函数实现,每隔 3 秒钟切换到下一个图片。左右控制按钮通过 <code>handlePrev</code> 和 <code>handleNext</code> 方法实现,点击按钮时切换到上一个或下一个图片。滚动到最后一张或第一张图片时,使用 <code>setTimeout</code> 函数等待过渡动画结束后,将当前索引重置到第一张或最后一张图片。</p>
<p>鼠标悬停暂停功能通过 <code>isPaused</code> 变量和 <code>mouseover</code> 和 <code>mouseout</code> 事件实现,当鼠标悬停在轮播图上时,设置 <code>isPaused</code> 为 <code>true</code>,停止定时滚动;当鼠标移开时,设置 <code>isPaused</code> 为 <code>false</code>,继续定时滚动。</p>
原文地址: https://www.cveoy.top/t/topic/mXeM 著作权归作者所有。请勿转载和采集!