原生js寫一個無縫輪播圖插件(支持vue)

輪播圖插件(Broadcast.js)

前言:寫這個插件的緣由

  • 前段時間準備用vue加上網易雲的nodejs接口,模擬網易雲音樂移動端。由於想本身寫一遍全部的代碼以及加固本身的flex佈局,因此沒有使用UI組件。在輪播圖部分,原本在vue裏面寫了一下,可是發現老是出現bug,因此後來準備封裝一個插件來實現。
  • 其次的一個緣由是,覺得這一學期學vue一直在用vue,發現本身之前學的原生js有點遺忘,因此想借這個機會再次複習一下js。

功能&介紹

  • 沒有引用第三方插件庫,原生js,封裝一個Broadcast對象,在此對象上展開,僅僅190多行代碼。
  • 目前主要實現了:無縫輪播,自動播放,PC端左右按鈕點擊切換,移動端手勢滑動切換。
  • 本身寫了一部分基礎的css樣式,能夠再次的基礎上修改爲本身喜歡的樣式。

展現界面&使用

Usage

普通頁面引用

  1. 複製github倉庫下面,src/js 文件下的 broadcast-me.js 放到本身項目文件中
  2. 複製github倉庫下面,src/css 文件下的 broadcast-me.css 放到本身項目文件中
  3. 在頁面中引入:javascript

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <!-- 引入插件的css文件 -->
      <link rel="stylesheet" href="./css/broadcast-me.css">
    </head>
    <body>
      <!-- 引入插件的js文件 -->
      <script src="./js/broadcast-me.js"></script>
    </body>
    </html>
  4. 在後面若是須要一個輪播圖,則實列化這個對象:css

    var box = document.getElementById('box');
    var imagesAndUrl = [{
      imgSrc : './img/1.jpg',
      linkHref : "#"
    },{
      imgSrc : './img/2.jpg',
      linkHref : '1'
    },{
      imgSrc : './img/3.jpg',
      linkHref : '#'
    },{
      imgSrc : './img/4.jpg',
      linkHref : '#'
    },{
      imgSrc : './img/5.jpg',
      linkHref : '#'
    }];
    // box => 你須要建立輪播圖的父級元素
    // imagesAndUrl => 數組,存放圖片地址以及圖片的鏈接地址
    var broadcast = new Broadcast(box,imagesAndUrl,{
          transitionTime : 800, // 動畫過渡時間,默認爲800ms
          intervalTime : 5000 // 圖片切換時間,默認爲5s
     });

VUE中引用

  1. 在vue中使用,在broadcast-me.js 文件最後加上:
// 向外界暴露Broadcas對象
module.exports = Broadcast;
  1. 在須要使用輪播的組件中,引入咱們的文件

vue中使用此框架

  1. 在模板文件中,採用自定義指令的方式,來插入咱們的輪播圖
<template>
  <div class="broadcast" v-broadcast="broadcastImg">
     <!-- 自定義指令broadcast,,形參 => broadcastImg 爲咱們的輪播圖數據 -->
  </div>
</template> imgSrc : './img/5.jpg',
  linkHref : '#'
}
  1. 添加自定義指令:
directives:{
  broadcast:{
    inserted:function(el,binding) {
      // binding.value 爲咱們傳入的形參,即圖片的地址和圖片點擊連接
      var broadcast = new Broadcast(el,binding.value,{
        transitionTime : 800, // 動畫過渡時間,默認爲800ms
        intervalTime : 5000 // 圖片切換時間,默認爲5s
      });
    }
  }
}

API

// 構造的對象
new Broadcast (el,imagesAndUrl,JSON)
屬性 說明 備註備註
el 你須要建立輪播圖的包裹(父級)元素 不寫報錯
imagesAndUrl 圖片的地址與圖片地址連接。數組對象 linkHref => 圖片點擊連接;imgSrc => 圖片地址 不寫報錯
JSON transitionTime => 動畫過渡時間, intervalTime => 動畫切換時間 默認:過渡時間 => 800ms 切換時間 => 5s

代碼編寫思路

dom 節點的動態生成
  1. 經過 el 的寬度,生成一個動態css加入到頁面當中
// 動態添加一些css樣式
let cssStr = `.broadcastMe .broadcastMe-list {width: ${(this.imagesAndUrl.length+2)*this.el.clientWidth}px;}.broadcastMe .broadcastMe-list .broadcastMe-item {width:${this.el.clientWidth}px;}`;

let styleNode = document.createElement('style');
styleNode.innerText = cssStr;
document.head.appendChild(styleNode)
  1. 經過字符串模板的形式,生成咱們須要的且符合無縫輪播的html字符串,加載el節點當中。
移動端手勢滑動

經過:touchstart => touchmove => touchend 完成一個滑動的全過程,並在touchmove事件當中,改變當前的left值,並在touchend事件當中判斷左右2邊的距離,進行翻頁仍是不變。html

// 移動端手指滑動
let stratPointX = 0;
let offsetX = 0;
this.el.addEventListener("touchstart", (e) => {
  stratPointX = e.changedTouches[0].pageX;
  offsetX = this.broadcastMeList.offsetLeft;
  this.animationMark = true;
})
this.el.addEventListener("touchmove", (e) => {
  let disX = e.changedTouches[0].pageX - stratPointX;
  let left = offsetX + disX;

  this.broadcastMeList.style.transitionProperty = 'none';
  this.broadcastMeList.style.left = left + 'px';
})
this.el.addEventListener("touchend", () => {
  let left = this.broadcastMeList.offsetLeft;
  // 判斷正在滾動的圖片距離左右圖片的遠近,
  this.index = Math.round(-left/this.el.clientWidth);
  this.animationMark = false;
  this.render();
})
渲染函數(☆)
Broadcast.prototype.render = function () {
  // 防抖控制
  if(this.animationMark) return;

  this.animationMark = true;
  // 修改broadcastMeList 的left值
  this.broadcastMeList.style.left = (-1)*this.el.clientWidth*this.index + 'px';
  this.broadcastMeList.style.transition = 'left ' + this.timer/1000 + 's';

  setTimeout(() => {
    // 添加判斷,防止出界
    if(this.index <= 0){
      // 無縫輪播,修改真實的left值,取消transition,形成視覺錯誤
      this.broadcastMeList.style.transitionProperty = 'none';
      this.index = this.imagesAndUrl.length;
      this.broadcastMeList.style.left = (-1)*this.el.clientWidth*this.index + 'px';
    }else if (this.index > this.imagesAndUrl.length){ 
      this.broadcastMeList.style.transitionProperty = 'none';
      this.index = 1;
      this.broadcastMeList.style.left = (-1)*this.el.clientWidth*this.index + 'px';
    }
    this.animationMark = false;
  },this.timer)

  this.renderSpot();
}

最後

由於才疏學淺,代碼纔剛剛寫完,測試較少,不少bug還未發現,若是發現問題,歡迎留言指出,敬請斧正。謝謝!!vue

相關文章
相關標籤/搜索