最近想搞一搞轮播图,就自己实现了一个,element的Carousel走马灯,饿了吗的vue-swipe以及swiper插件,都是很好的学习对象
- vue
vue的话简单很多,毕竟其封装了动画渲染,轮播图当然需要v-for去渲染,vue提供了<transition-group>
组件来实现列表的渲染
先把代码贴出来吧
<style lang="scss" rel="stylesheet/scss" scoped>
.swipe {
position: relative;
height: 512px;
width: 1024px;
overflow: hidden;
background-color: #fff;
&__list{
width: 100%;
height: 100%;
li {
position: absolute;
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
}
}
}
&__dian {
position: absolute;
z-index: 10;
top: 480px;
width: 100%;
margin: 0 auto;
text-align: center;
font-size: 0;
span {
display: inline-block;
height: 10px;
width: 30px;
margin: 0 6px;
background-color: #49b23c;
cursor: pointer;
}
.active {
background-color: #B20F12;
}
}
&__control {
position: absolute;
z-index: 10;
top: 206px;
width: 100%;
display: flex;
justify-content: space-between;
cursor: pointer;
.prev {
&:hover {
color: red;
font-weight: bold;
}
}
.next {
&:hover {
color: red;
font-weight: bold;
}
}
}
.list-enter-to {
transition: all 1s ease;
transform: translateX(0);
}
.list-leave-active {
transition: all 1s ease;
transform: translateX(-100%)
}
.list-enter {
transform: translateX(100%)
}
.list-leave {
transform: translateX(0)
}
/* .list-enter-active, .list-leave-active {
transition: opacity 1s;
}
.list-enter, .list-leave-to {
opacity: 0;
}*/
}
</style>
<template>
<div class="swipe" @mouseenter.stop="handleStop" @mouseleave.stop="handleGo">
<transition-group name="list" tag="ul" class="swipe__list">
<li v-for="(item,index) in imgList" :key="index"
class="list-item" v-show="index===currentIndex">
<a href="#">
<img alt="" :src="item.src">
</a>
</li>
</transition-group>
<div class="swipe__dian">
<span v-for="(item,index) in imgList.length" :class="{'active':index===currentIndex}" @mouseover="handleChange(index)"></span>
</div>
<div class="swipe__control" v-show="control">
<dl-icon class="prev" type="Left" @click.native="handleChange(prevIndex)" size="1.1"></dl-icon>
<dl-icon class="next" type="youjiantou1" @click.native="handleChange(nextIndex)" size="1.6"></dl-icon>
</div>
</div>
</template>
<script>
import {DlIcon} from 'comp@'
export default {
components: {DlIcon},
data () {
return {
imgList: [
{src: '../../../../static/image/1.png'},
{src: '../../../../static/image/2.png'},
{src: '../../../../static/image/3.png'},
{src: '../../../../static/image/4.png'},
{src: '../../../../static/image/5.png'}
],
index: 0,
currentIndex: 0,
timer: '',
control: false
}
},
computed: {
prevIndex () {
if (this.currentIndex === 0) {
return this.imgList.length - 1
} else {
return this.currentIndex - 1
}
},
nextIndex () {
if (this.currentIndex === this.imgList.length - 1) {
return 0
} else {
return this.currentIndex + 1
}
}
},
methods: {
autoPlay () {
this.currentIndex++
if (this.currentIndex > this.imgList.length - 1) {
this.currentIndex = 0
}
},
handleStop () {
this.control=true
clearInterval(this.timer)
this.timer = null
},
handleGo () {
this.control=false
this.timer=setInterval(() => {
this.autoPlay()
}, 3000)
},
handleChange (index) {
this.currentIndex = index
}
},
created () {
this.$nextTick(() => {
this.handleGo
})
}
}
</script>
这些代码都通俗易懂,其实没什么好说的,也就是功能的实现,以及css的最基本使用,需要值得一提的是,我这边的image采用的是本地图片,放在static目录下,当然使用服务器链接也没问题,li元素的循环应该使用v-show来判断,而不是v-if,具体可以看官网解释,很清晰易懂,用定时器改变 currentIndex 实现轮播
效果:
- jquery
jquery实现当然不方便了,但是它操作dom很方便,动画效果也很赞,so,也可以实现一下,对比上面的vue实现,我这里先贴出html与css的基本结构,当然可以看出来jquery的思路 是放一排,相当于雪碧图
<style>
* {
margin: 0;
padding:0;
}
ul{
list-style: none;
}
.swipe{
width: 1024px;
height: 512px;
margin: 100px auto;
position: relative;
overflow: hidden;
}
.list {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.list li{
float: left;
}
img {
width: 100%;
height: 100%;
}
.dian{
position: absolute;
bottom: 10px;
width: 100%;
text-align: center;
font-size: 0;
}
.dian li{
width: 10px;
height: 10px;
background:rgba(0,0,0,0.5);
border-radius: 100%;
display: inline-block;
margin: 0 5px;
cursor: pointer;
}
/*默认为不可见,与v-show的false*/
.control{
display: none;
}
.control span{
display: block;
width: 50px;
height: 100px;
background: rgba(0,0,0,0.6);
color: #fff;
font-size: 40px;
line-height: 100px;
text-align: center;
cursor:pointer;
}
.control .prev{
position: absolute;
left: 0;
top: 50%;
margin-top: -50px;
}
.control .next{
position: absolute;
right: 0;
top: 50%;
margin-top: -50px;
}
/*类似vue动态的class*/
.dian .active{
background-color: #fff;
}
</style>
<div class="swipe">
<!--这里就代替vue的列表渲染组件-->
<ul class="list">
<li><a href="#"><img src="image/1.png" alt=""></a></li>
<li><a href="#"><img src="image/2.png" alt=""></a></li>
<li><a href="#"><img src="image/3.png" alt=""></a></li>
<li><a href="#"><img src="image/4.png" alt=""></a></li>
<li><a href="#"><img src="image/5.png" alt=""></a></li>
</ul>
<!--这里就不直接写出来了,vue中是动态根据图片length来渲染dom,这边仿造一样即可-->
<ul class="dian"></ul>
<!--这里用span元素去替代vue中的icon-->
<div class="control">
<span class="prev"><</span>
<span class="next">></span>
</div>
</div>
现在就可以去用jquery的dom操作去实现轮播的效果,
首先肯定是根据图片数量,将dom全部渲染完毕
for (var j = 0; j < $('.list li').length; j++) {
$('.dian').append('<li></li>');
}
vue中左右按钮的控制与隐藏
$('.swipe').hover(function(){
$('.control').show();
},function(){
$('.control').hide();
});
jquery的轮播,搞了蛮久,在网上看到了解决办法,因为我这样的实现和vue完全不同,滑动效果就是雪碧图不同时间展示的效果实现而已,最后一张图片必须要copy第一张图片,这样才可以实现无缝滑动效果,因为动态动画效果改变图片left元素值,为0时会有问题,因直接将left元素重置为0,再left 一个图片宽度
var firstimg=$('.list li').first().clone(); //复制第一张图片
$('.list').append(firstimg).width($('.list li').length*($('.list img').width()));
timer=setInterval(function(){
i++;
if (i==$('.list li').length) {
i=1;
$('.list').css({left:0});//保证无缝轮播,设置left值
}
//进行下一张图片
$('.list').stop().animate({left:-i*1024},500);
//圆点跟着变化
if (i==$('.list li').length-1) {
// 这段代码在jquery中很常用,代表着index为0的元素新增class,再将其他不为0的元素全部去除active的class
$('.dian li').eq(0).addClass('active').siblings().removeClass('active');
}else{
$('.dian li').eq(i).addClass('active').siblings().removeClass('active');
}
},1000);
鼠标hover 和 左右按钮点击其实也就差不多了,贴一下js全部代码
$(function(){
// 类似vue中的currentIndex
var i=0;
var timer=null;
for (var j = 0; j < $('.list li').length; j++) {
$('.dian').append('<li></li>');
}
//默认情况下的第一个圆点为active
$('.dian li').first().addClass('active');
$('.swipe').hover(function(){
$('.control').show();
},function(){
$('.control').hide();
});
var firstimg=$('.list li').first().clone(); //复制第一张图片 放在最后一个的后面
$('.list').append(firstimg).width($('.list li').length*($('.list img').width()));
//轮播
timer=setInterval(function(){
i++;
if (i==$('.list li').length) {
i=1; // 注意这里i 是为1 承转下面的animate -1024
$('.list').css({left:0});// 这里必须重置
}
$('.list').stop().animate({left:-i*1024},500);
if (i==$('.list li').length-1) {
$('.dian li').eq(0).addClass('active').siblings().removeClass('active');
}else{
$('.dian li').eq(i).addClass('active').siblings().removeClass('active');
}
},1000);
//鼠标操作
$('.swipe').hover(function(){
clearInterval(timer);
},function(){
timer=setInterval(function(){
i++;
if (i==$('.list li').length) {
i=1;
$('.list').css({left:0});
};
$('.list').stop().animate({left:-i*1024},500);
if (i==$('.list li').length-1) {
$('.dian li').eq(0).addClass('active').siblings().removeClass('active');
}else{
$('.dian li').eq(i).addClass('active').siblings().removeClass('active');
}
},1000)
});
//left按钮
$('.prev').click(function(){
i--;
if (i==-1) {
i=$('.list li').length-2;
$('.list').css({left:-($('.list li').length-1)*1024});
}
$('.list').stop().animate({left:-i*1024},500);
$('.dian li').eq(i).addClass('active').siblings().removeClass('active');
});
// right按钮
$('.next').click(function(){
i++;
if (i==$('.list li').length) {
i=1;
$('.list').css({left:0});
};
$('.list').stop().animate({left:-i*1024},500);
if (i==$('.list li').length-1) {
$('.dian li').eq(0).addClass('active').siblings().removeClass('active');
}else{
$('.dian li').eq(i).addClass('active').siblings().removeClass('active');
};
});
//hover圆点
$('.dian li').mouseover(function(){
var _index=$(this).index();
// 这里就是vue中的保持currentIndex
i = _index;
$('.list').stop().animate({left:-_index*1024},300);
$('.dian li').eq(_index).addClass('active').siblings().removeClass('active');
});
})
当然,jqeury提供了几种动画的实现,如果你需要上下滑动和淡入淡出,不需要和上面一样那么麻烦,我参考了这篇文章,so,也贴一下实现吧,注意css只需要将注释即可,html不用动,直接就贴一下代码了,不说明了
$(function () {
var i = 0;
var timer;
for (var j = 0; j < $('.list li').length; j++) {
$('.dian').append('<li></li>');
}
//默认设置第一张图片显示,其余隐藏
$('.list li').eq(0).show().siblings('.list li').hide();
$('.dian li').eq(0).addClass('active').siblings('.dian li').removeClass('active');
timer = setInterval(showList,2000);
$('.dian li').hover(function () {
i = $(this).index();
clearInterval(timer);
show();
},function () {
timer = setInterval(showList,2000);
})
//鼠标点击左侧箭头触发效果
$('.control.prev').click(function () {
clearInterval(timer);
if (i == 0){
i = 5; //注意此时i的数值
}
i --;
show();
timer = setInterval(showList,2000);
})
//鼠标点击右侧箭头触发效果
$('.control.next').click(function () {
clearInterval(timer);
if (i == 4){
i = -1; //注意此时i的数值
}
i ++;
show();
})
})
function showList() {
i++;
if (i == 5){
i = 0;
}
//用fadeIn()与fadeOut()的淡入淡出,这里你可以实现你想要的动画效果
$('.list li').eq(i).fadeIn(600).siblings('.list li').fadeOut(600);
$('.dian li').eq(i).addClass('active').siblings('.dian li').removeClass('active');
}
function show() {
$('.list li').eq(i).fadeIn(600).siblings('.list li').fadeOut(600);
$('.dian li').eq(i).addClass('active').siblings('.dian li').removeClass('active');
}
最后搞完会发现,vue的代码量简单更少直观易懂,毕竟封装的好啊。
据说这个原生js封装的很不错,有机会可以看看 先记录一下,地址链接