輪播呢,也是各種網(wǎng)站上常見的一種展示效果,這里我來寫一寫實(shí)現(xiàn)輪播的一些簡(jiǎn)單方法。
//不知道為什么系統(tǒng)吃了代碼里面的img標(biāo)簽,大佬們有解決方式么?
1.原生js輪播
原生的輪播效果,這里實(shí)現(xiàn)的原理:有個(gè)一個(gè)放置圖片列表的塊級(jí)元素,放置所有的圖片,我這里使用的是橫向的列表;他的父元素為一個(gè)展示塊,寬高為一張圖片的寬高,利用overflow:hidden屬性,每次只展示一張圖片,隱藏其他圖片,再用js控制圖片列表定時(shí)或者其他方式左移右移即可實(shí)現(xiàn)簡(jiǎn)單的輪播了。下圖圖片處為overflow:hidden的父元素,1500*200為圖片列表。
為了讓輪播更流暢,在最后一張圖片后面插入第一張圖片。
.box{
width:300px;
height:200px;
margin:100px auto;
overflow: hidden;
}
.img-g{
width:1500px;
height:200px;
}
.img-g img{
width:300px;
height:200px;
}
將圖片列表position設(shè)為relative,就可以利用偏移來移動(dòng)圖片了,為了方便,這里將left屬性內(nèi)聯(lián)到img-g里。
如left為-100px時(shí)
然后用js獲得圖片列表的style.left,使用定時(shí)器控制他的偏移量,就可以實(shí)現(xiàn)簡(jiǎn)單的輪播了。
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'
}
}
不過光有圖片的移動(dòng)還不夠,為了讓圖片切換更自然一點(diǎn),可以加入css3對(duì)left的過渡。
不過最后一張切換到第一張時(shí)的過渡是相反的,因此還是使用js控制過渡屬性。
從最后一張圖片到第一張圖片的過渡稍微麻煩一些,我最后使用定時(shí)器,讓圖片滑到最后一張,等過渡動(dòng)畫完成之后,取消過渡動(dòng)畫,切換到第一張之后再開啟動(dòng)畫。這部分代碼如下
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';
}
}
到這里,輪播的功能已經(jīng)實(shí)現(xiàn)了,還可以為它加上幾個(gè)小圓點(diǎn),控制輪播現(xiàn)在正在播放的圖。
小圓點(diǎn)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%;
}
小圓點(diǎn)被點(diǎn)擊時(shí),圖片滑動(dòng)至小圓點(diǎn)對(duì)應(yīng)的圖片,并且圖片滑動(dòng)時(shí)小圓點(diǎn)也跟著變化,我在每個(gè)小圓點(diǎn)屬性中加入了data-屬性,該屬性可被js獲取。
為小圓點(diǎn)加入事件,被點(diǎn)擊時(shí)滑動(dòng)對(duì)應(yīng)的偏移量。
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)';
}
常見的輪播還有一種效果,就是鼠標(biāo)只在圖片上的時(shí)候,暫停輪播;鼠標(biāo)離開時(shí)繼續(xù)輪播。
以這種思路,很容易實(shí)現(xiàn)想要的效果。
p.onmouseover=function(){
clearInterval(window.timer)
}
p.onmouseout=function(){
window.timer=setInterval(move,3000);
}
實(shí)際效果可以看下面鏈接:
https://zkhchris.github.io/FE_basic/hc/Carousel/carousel_pure_js.html
2.css3輪播
這里使用css3動(dòng)畫實(shí)現(xiàn)了一個(gè)漸顯漸隱的效果,使用absolute定位,讓圖片列表中的圖片疊加在一起,通過動(dòng)畫控制z-index和透明度實(shí)現(xiàn)漸顯漸隱。
absolute元素相對(duì)于第一個(gè)定位不是static的父元素定位,因此該元素都疊加在一個(gè)顯示塊中。
然后使用css3動(dòng)畫按時(shí)間循環(huán)改變他們的透明度和z-index,即可完成簡(jiǎn)單的輪播效果。
這里每張圖片占用的動(dòng)畫時(shí)間為4s,總動(dòng)畫時(shí)間即為16s。淡入淡出都是1s,占用總時(shí)間約為6%,在最頂層的時(shí)間為3s,占用總時(shí)間18.7%;按此比例設(shè)置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;
}
}
這時(shí)圖片都可以按時(shí)間循環(huán)出現(xiàn),不過他們現(xiàn)在是同時(shí)出現(xiàn),同時(shí)消失的,為圖片加上延時(shí)即可完成效果。
#img2{
animation-delay: 0s;
}
#img2{
animation-delay: 4s;
}
#img3{
animation-delay: 8s;
}
#img4{
animation-delay: 12s;
}
css3輪播可實(shí)現(xiàn)輪播效果,但是沒有辦法控制現(xiàn)在要播哪張圖片,因此盡量使用js控制輪播效果。
https://zkhchris.github.io/FE_basic/hc/Carousel/css3carousel.html
3.vue輪播
使用vue輪播,可以使用列表渲染動(dòng)態(tài)加入想輪播的圖片,使用vue自帶的列表過渡,可實(shí)現(xiàn)輪播效果。
這里使用非無定位輪播框父元素加上子元素為absolute圖片,配合v-show實(shí)現(xiàn)輪播效果。
列表渲染圖片
<template>
<div id='swiper_img_box'>
<ul class='swiper_img_ul'>
</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來控制圖片是否顯示,在使用定時(shí)器來定時(shí)修改當(dāng)前顯示的圖片,定時(shí)器掛在了mounted上。
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
}
},
這樣,通過定時(shí)器,可以控制圖片的輪播了,但是沒有過渡效果,輪播很突兀,加上過渡效果就好了。
<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)
}
在加上常見的鼠標(biāo)mouseover暫停,mouseout繼續(xù),點(diǎn)擊按鈕輪播至所點(diǎn)擊按鈕對(duì)應(yīng)的圖片。
<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()
}
}
這時(shí)輪播效果就實(shí)現(xiàn)的差不多了,不過這個(gè)vue輪播我是寫成了單文件組件的形式,無法預(yù)覽,就在下方貼上這個(gè)代碼。
謝謝大家閱讀,希望大佬們多多指點(diǎn)。
swiper.vue
<template>
<div id='swiper_img_box'>
<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>