js實(shí)現(xiàn)輪播效果幾種方式

輪播呢,也是各種網(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為圖片列表。

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設(shè)為relative,就可以利用偏移來移動(dòng)圖片了,為了方便,這里將left屬性內(nèi)聯(lián)到img-g里。
如left為-100px時(shí)

image.png

然后用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)畫。這部分代碼如下

image.png
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è)顯示塊中。

image.png

然后使用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'>
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來控制圖片是否顯示,在使用定時(shí)器來定時(shí)修改當(dāng)前顯示的圖片,定時(shí)器掛在了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
    }
    },

這樣,通過定時(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'>
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>

謝謝大家閱讀,希望大佬們多多指點(diǎn)!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,676評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,730評(píng)論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,873評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,266評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,482評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,036評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,846評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,025評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,279評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評(píng)論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,751評(píng)論 3 394
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,016評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容