网络公司网站源码/搜索引擎优化的概念
网上有许多轮播图案例,但只有极少数做了两个方向的滑动过渡效果。而我就是其中一个!所以来关注hans774882968,看技术干货!
先看效果图
HTML
<!DOCTYPE html>
<html>
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><title>轮播图图片切换</title><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"><link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"><link rel="stylesheet" type="text/css" href = "./index.css" /><style type="text/css"></style><script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script><script src="https://cdn.staticfile.org/vue/2.5.2/vue.min.js"></script><script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body><main id="app" class="container"><div class="img-wrap"><div class="wrap" v-for="(item,idx) in imgs" :key="idx"><transition :name="imgAnime"><img v-show="curIdx === idx" :key="item.idx" :src="item.src" /></transition></div><div class="left-btn" @click="imgChange(-1)"><</div><div class="right-btn" @click="imgChange(1)">></div></div></main><script src="./index.js"></script>
</body>
</html>
.img-wrap
是整个轮播图组件的根元素。.wrap
则是被绝对定位控制在我们期望的位置。
若干个图片,只有一个能显示,其他的应该display: none;
所以用v-show和curIdx
来控制。
CSS
body{margin: 0;background-color: wheat;
}div{box-sizing: border-box;
}.container{width: 100%;height: 100vh;display: flex;flex-direction: column;justify-content: center;align-items: center;
}.img-wrap{width: 600px;height: 225px;position: relative;overflow: hidden;/* 隐藏突出部分 */
}.wrap{width: 100%;height: 100%;position: absolute;top: 0;left: 0;
}img{width: 100%;height: 100%;
}
/* right=左to右 */
.img-play-right-enter-active,.img-play-right-leave-active,
.img-play-left-enter-active,.img-play-left-leave-active{transition: all .6s;
}
/* 左to右和右to左的类名呈现一个reverse的关系 */
.img-play-right-enter,.img-play-left-leave-to {transform: translateX(100%);
}.img-play-right-enter-to,.img-play-left-leave{transform: translateX(0);
}
.img-play-right-leave,.img-play-left-enter-to{transform: translateX(0);
}
.img-play-right-leave-to,.img-play-left-enter{transform: translateX(-100%);
}.left-btn,.right-btn{position: absolute;width: 32px;height: 32px;border-radius: 50%;background-color: rgba(0,0,0,.2);top: 50%;margin-top: -12px;font-size: 20px;font-weight: bold;color: white;line-height: 29px;text-align: center;user-select: none;cursor: pointer;
}.left-btn{left: 16px;
}.right-btn{right: 16px;
}
.wrap
被绝对定位控制在-100%、0%和100%(相对.img-wrap
的宽度)的位置,然后用translateX()
和vue提供的<transition>
来控制进入阶段(enter阶段)的起点、终点和离开阶段(leave阶段)的起点、终点。详细写法可以看代码的注释。
.img-wrap
用overflow: hidden;
来隐藏.wrap
的突出部分。
但还有一个问题没解决:怎么实现两个方向都有动画?参考https://www.cnblogs.com/gsgs/p/6698494.html,我们发现,直接动态修改<transition>
的name属性即可(注意,vue官方文档没有提到这个)。
.left-btn
和.right-btn
用绝对定位跑到期望的位置,然后进行一些样式上的处理,都是基本操作了。
JS
"use strict";function main() {let vm = new Vue({el: '#app',data() {return {imgs: [{idx: 0,src: './imgs/1.jfif'},{idx: 1,src: './imgs/2.jfif'},{idx: 2,src: './imgs/3.jfif'}],curIdx: 0,timer: null,imgAnime: 'img-play-right'/* transition的name属性也可以动态变化~这一事实来自:* https://www.cnblogs.com/gsgs/p/6698494.html */}},mounted(){this.newTimer()},methods: {newTimer(){this.timer = setInterval(() => {this.imgChange(1)},3000)},stopTimer(){clearInterval(this.timer)},imgChange(v) {this.imgAnime = v === -1 ? 'img-play-left' : 'img-play-right'let l = this.imgs.lengththis.curIdx = ((this.curIdx + v) % l + l) % lthis.stopTimer()this.newTimer()}}});
}$(document).ready(main);
这里为了方便,对于没点击按钮时,自动放下一张图片的逻辑,也用this.imgChange(1)
实现了。这就导致每次setInterval调用1次就被清空。反正不影响效果,不想改代码了。
it is not bug, it is feature!