js实现轮播效果几种方式
轮播呢,也是各种网站上常见的一种展示效果,这里我来写一写实现轮播的一些简单方法。
//不知道为什么系统吃了代码里面的img标签,大佬们有解决方式么?
1.原生js轮播
原生的轮播效果,这里实现的原理:有个一个放置图片列表的块级元素,放置所有的图片,我这里使用的是横向的列表;他的父元素为一个展示块,宽高为一张图片的宽高,利用overflow:hidden属性,每次只展示一张图片,隐藏其他图片,再用js控制图片列表定时或者其他方式左移右移即可实现简单的轮播了。下图图片处为overflow:hidden的父元素,1500*200为图片列表。
image.png为了让轮播更流畅,在最后一张图片后面插入第一张图片。
image.png.box{
width:300px;
height:200px;
margin:100px auto;
overflow: hidden;
}
.img-g{
width:1500px;
height:200px;
}
.img-g img{
width:300px;
height:200px;
}
将图片列表position设为relative,就可以利用偏移来移动图片了,为了方便,这里将left属性内联到img-g里。
如left为-100px时
然后用js获得图片列表的style.left,使用定时器控制他的偏移量,就可以实现简单的轮播了。
let p=document.getElementsByClassName('img-g')[0];
let timer=setInterval(move,2000);
function move(){
if(parseInt(p.style.left)>-1200){
p.style.left=parseInt(p.style.left)-300+'px'
console.log(p.style.left)
}else{
p.style.left='-300px'
}
}
不过光有图片的移动还不够,为了让图片切换更自然一点,可以加入css3对left的过渡。
不过最后一张切换到第一张时的过渡是相反的,因此还是使用js控制过渡属性。
从最后一张图片到第一张图片的过渡稍微麻烦一些,我最后使用定时器,让图片滑到最后一张,等过渡动画完成之后,取消过渡动画,切换到第一张之后再开启动画。这部分代码如下
let p=document.getElementsByClassName('img-g')[0];
let timer=setInterval(move,2000);
function move(){
if(parseInt(p.style.left)>-1200){
p.style.left=parseInt(p.style.left)-300+'px'
p.style.transition='left 1s';
if(parseInt(p.style.left)<=-1200){
console.log('t')
setTimeout(function(){
p.style.left='0px'
p.style.transition='left 0s';
},1000)
}
}else{
p.style.left='0px'
p.style.transition='left 0s';
}
}
到这里,轮播的功能已经实现了,还可以为它加上几个小圆点,控制轮播现在正在播放的图。
小圆点html
<div class='button-g'>
<span data-index='0' ></span>
<span data-index='1'></span>
<span data-index='2'></span>
<span data-index='3'></span>
</div>
.button-g{
position:relative;
top:-20px;
text-align:center;
}
.button-g span{
display:inline-block;
position:relative;
z-index:10;
width:10px;
height:10px;
margin:0 5px;
border-radius:100%;
}
小圆点被点击时,图片滑动至小圆点对应的图片,并且图片滑动时小圆点也跟着变化,我在每个小圆点属性中加入了data-属性,该属性可被js获取。
为小圆点加入事件,被点击时滑动对应的偏移量。
for(let i=0;i<button.length;i++){
button[i].onclick=function(){
p.style.left=-300*this.getAttribute('data-index')+'px'
tog(this.getAttribute('data-index'))
}
}
function tog(index){
if(index>3){tog(0);return;}
for(let i=0;i<button.length;i++){
button[i].style.backgroundColor='#eee'
}
button[index].style.backgroundColor='rgb(215, 81, 15)';
}
常见的轮播还有一种效果,就是鼠标只在图片上的时候,暂停轮播;鼠标离开时继续轮播。
以这种思路,很容易实现想要的效果。
p.onmouseover=function(){
clearInterval(window.timer)
}
p.onmouseout=function(){
window.timer=setInterval(move,3000);
}
实际效果可以看下面链接:
https://zkhchris.github.io/FE_basic/hc/Carousel/carousel_pure_js.html
2.css3轮播
这里使用css3动画实现了一个渐显渐隐的效果,使用absolute定位,让图片列表中的图片叠加在一起,通过动画控制z-index和透明度实现渐显渐隐。
absolute元素相对于第一个定位不是static的父元素定位,因此该元素都叠加在一个显示块中。
然后使用css3动画按时间循环改变他们的透明度和z-index,即可完成简单的轮播效果。
这里每张图片占用的动画时间为4s,总动画时间即为16s。淡入淡出都是1s,占用总时间约为6%,在最顶层的时间为3s,占用总时间18.7%;按此比例设置keyframe
.imglist img{
width:300px;
height:200px;
position:absolute;
animation: show 16s infinite;
}
@keyframes show{
0%{
opacity:0;
z-index:2;
}
6%,25%{
opacity:1;
z-index: 1;
}
31%,100%{
opacity:0;
z-index:0;
}
}
这时图片都可以按时间循环出现,不过他们现在是同时出现,同时消失的,为图片加上延时即可完成效果。
#img2{
animation-delay: 0s;
}
#img2{
animation-delay: 4s;
}
#img3{
animation-delay: 8s;
}
#img4{
animation-delay: 12s;
}
css3轮播可实现轮播效果,但是没有办法控制现在要播哪张图片,因此尽量使用js控制轮播效果。
https://zkhchris.github.io/FE_basic/hc/Carousel/css3carousel.html
3.vue轮播
使用vue轮播,可以使用列表渲染动态加入想轮播的图片,使用vue自带的列表过渡,可实现轮播效果。
这里使用非无定位轮播框父元素加上子元素为absolute图片,配合v-show实现轮播效果。
列表渲染图片
<template>
<div id='swiper_img_box'>
<ul class='swiper_img_ul'>
image.png
</ul>
<ul class='buttonG'>
<span v-for='(img,index) in imgs' :key='index' ></span>
</ul>
</div>
</template>
<style>
.swiper_img_ul{
height:300px;
}
.swiper_img_ul img{
position:absolute;
}
#swiper_img_box{
position:relative;
width:300px;
height:300px;
overflow:hidden;
}
.buttonG{
position:absolute;
bottom:0;
}
.circle{
display:inline-block;
width:15px;
height:15px;
border-radius:100%;
margin-left:10px;
}
</style>
使用v-show来控制图片是否显示,在使用定时器来定时修改当前显示的图片,定时器挂在了mounted上。
image.png mounted:function(){
this.timer=setInterval(this.changeIndex,2000)
},
methods:{
changeIndex(){
if(this.showIndex>=this.imgs.length-1){
this.showIndex=0
}else{
this.showIndex++
}
}
data () {
return {
imgs:[
{
src:'../../dist/7.gif',
alt:'1'
},{
src:'../../dist/home_06.gif',
alt:'2'
},{
src:'../../dist/home_08.gif',
alt:'3'
},{
src:'../../dist/home_12.gif',
alt:'4'
}
],
showIndex:0
}
},
这样,通过定时器,可以控制图片的轮播了,但是没有过渡效果,轮播很突兀,加上过渡效果就好了。
<transition-group name='image' tag="ul" class='swiper_img_ul'>
.image-enter-active {
transform: translateX(0);
transition: all 1s ease;
}
.image-leave-active {
transform: translateX(-100%);
transition: all 1s ease;
}
.image-enter {
transform: translateX(100%)
}
.image-leave {
transform: translateX(0)
}
在加上常见的鼠标mouseover暂停,mouseout继续,点击按钮轮播至所点击按钮对应的图片。
<transition-group name='image' tag="ul" class='swiper_img_ul'>
<img ...... @mouseover='stop' @mouseout='start'>
</transition-group>
<ul class='buttonG'>
<span ...... @click='goto(index)'></span>
</ul>
methods:{
changeIndex(){
if(this.showIndex>=this.imgs.length-1){
this.showIndex=0
}else{
this.showIndex++
}
},
stop(){
console.log('1')
clearInterval(this.timer)
},
start(){
this.timer=setInterval(this.changeIndex,2000)
},
goto(i){
this.showIndex=i
this.stop()
this.start()
}
}
这时轮播效果就实现的差不多了,不过这个vue轮播我是写成了单文件组件的形式,无法预览,就在下方贴上这个代码。
谢谢大家阅读,希望大佬们多多指点。
swiper.vue
<template>
<div id='swiper_img_box'>
image.png
<ul class='buttonG'>
<span v-for='(img,index) in imgs' :key='index' :class="[index==showIndex ? 'color' : 'white', 'circle']" @click='goto(index)'></span>
</ul>
</div>
</template>
<script>
export default{
name:'swiper',
data () {
return {
imgs:[
{
src:'../../dist/7.gif',
alt:'1'
},{
src:'../../dist/home_06.gif',
alt:'2'
},{
src:'../../dist/home_08.gif',
alt:'3'
},{
src:'../../dist/home_12.gif',
alt:'4'
}
],
showIndex:0
}
},
mounted:function(){
this.timer=setInterval(this.changeIndex,2000)
}
,
methods:{
changeIndex(){
if(this.showIndex>=this.imgs.length-1){
this.showIndex=0
}else{
this.showIndex++
}
},
stop(){
clearInterval(this.timer)
},
start(){
this.timer=setInterval(this.changeIndex,2000)
},
goto(i){
this.showIndex=i
this.stop()
this.start()
}
}
}
</script>
<style>
.swiper_img_ul{
height:300px;
}
.swiper_img_ul img{
position:absolute;
}
#swiper_img_box{
position:relative;
width:300px;
height:300px;
overflow:hidden;
}
.buttonG{
position:absolute;
bottom:0;
}
.circle{
display:inline-block;
width:15px;
height:15px;
border-radius:100%;
margin-left:10px;
}
.white{
background-color:#fff;
}
.color{
background-color:#f00;
}
.image-enter-active {
transform: translateX(0);
transition: all 1s ease;
}
.image-leave-active {
transform: translateX(-100%);
transition: all 1s ease;
}
.image-enter {
transform: translateX(100%)
}
.image-leave {
transform: translateX(0)
}
</style>