天天看點

原生js經典案例*輪播圖

原生js經典案例*輪播圖

 直接來代碼!

h5

<div class="banner" id="banner">
        <ul class="imgBox">
            <li class="active"><img src="" alt=""></li>
            <li ><img src="" alt=""></li>
            <li ><img src="" alt=""></li>
            <li ><img src="" alt=""></li>
            <li ><img src="" alt=""></li>
            <li ><img src="" alt=""></li>
        </ul>
        <!-- 焦點 -->
        <ol class="pointBox"></ol>
        <!-- 左右切換 -->
        <div class="prev">&lt;</div>
        <div class="next">&gt;</div>
</div>
           

css樣式

<style>
           /* 取消預設樣式 */
        ul, ol, li {
          list-style: none;
        }
        
        .banner {
          width: 600px;
          height: 400px;
          border: 10px solid orangered;
          margin: 30px auto;
          position: relative;
        }
    
        .banner > ul {
          width: 100%;
          height: 100%;
          position: relative;
        }
        
        .banner > ul > li {
          width: 100%;
          height: 100%;
          position: absolute;
          left: 0;
          top: 0;
          display: flex;
          justify-content: center;
          align-items: center;
          /* 隐藏照片 */
          opacity: 0;
          transition: opacity .5s linear;
        }
        .banner > ul > li > img {
            width: 100%;
            height: 100%;
        }
        /* 顯示照片 */
        .banner > ul > li.active {
          opacity: 1;
        }
        /* 設定焦點 */
        .banner > ol {
          width: 200px;
          height: 30px;
          background-color: rgba(0, 0, 0, .3);
          position: absolute;
          left: 30px;
          bottom: 30px;
          border-radius: 15px;
    
          display: flex;
          
          justify-content: space-evenly;
          align-items: center;
        }
    
        .banner > ol > li {
          width: 20px;
          height: 20px;
          background-color: #fff;
          border-radius: 50%;
          cursor: pointer;
        }
        
        .banner > ol > li.active {
          background-color: red;
        }
    
        .banner:hover > div {
          display: flex;
        }
        /* 左右切換 */
        .banner > div {
          width: 30px;
          height: 40px;
          background-color: rgba(0, 0, 0, .2);
          display: flex;
          justify-content: center;
          align-items: center;
          color: #fff;
          font-size: 20px;
          position: absolute;
          top: 50%;
          transform: translateY(-50%);
          cursor: pointer;
          display: none;
        }
    
        .banner > div:hover {
          background-color: rgba(0, 0, 0, .5);
        }
    
        .banner > div.prev {
          left: 0;
        }
    
        .banner > div.next {
          right: 0;
        }
      </style>
           

js部分,ES6類文法 面向對象思想來實作

class Banner{
   // 擷取元素,
  constructor(select){
      this.ele=document.querySelector(select)
        // 擷取圖檔盒子,擷取焦點
      this.imgBox=this.ele.querySelector('.imgBox')
      this.pointBox=this.ele.querySelector('.pointBox')
        //為了計數用
      this.index=0
        // 為了定時器自動輪播用
      this.timer=0
        // 調用方法
      this.init()
  }

  init(){
      this.setPoint()
      this.autoPlay()
      this.overOut()
      this.bindEvent()
  }
    //  設定生成焦點,
  setPoint () {
        // 定義焦點數量,和圖檔數量相等
      const pointNum=this.imgBox.children.length
         // 循環焦點
      for (let i = 0; i < pointNum; i++) {
        // 生成焦點元素
          const li = document.createElement('li')
        // 添加類名,為了下面友善使用,添加自定義屬性計數值
          li.classList.add('point')
          li.dataset.i=i
        // 預設第一個焦點添加active類名
          if(i===0) li.classList.add('active')
        // 插入焦點盒子
          this.pointBox.appendChild(li)
      }
      // 重新設定焦點寬度,為了美觀
      this.pointBox.style.width = pointNum*30+'px'
  }
  // 切換一張,為了實作自動輪播,先搞定切換一張
  changeOne (type) {
    // 初始 imgBox pointBox 去除active樣式
    this.imgBox.children[this.index].classList.remove('active')
    this.pointBox.children[this.index].classList.remove('active')
    // type參數為了判斷向後一張 或向前一張 或點選一張
    switch (type) {
        case true:
            // 判斷true 就是加一張
            this.index ++
            break;
        case false:
            // 判斷false 就是上一張
            this.index--
            break;
        default:
            // 當使用者點選point,就是該一張
            this.index = type

    }
    // 界限判定,到達最後一張要切到第一張,或倒着第一張切換到最後一張
    if(this.index >= this.imgBox.children.length) this.index = 0
    if(this.index < 0) this.index = this.imgBox.children.length - 1
    // 給這一張或這一個焦點添加active
    this.imgBox.children[this.index].classList.add('active')
    this.pointBox.children[this.index].classList.add('active')
  }
    // 自動輪播,定時器實作,可以改變輪播速度
  autoPlay () {
      this.timer = setInterval (() => this.changeOne(true),1500)
  }
    // 滑鼠移入,暫停定時器,停止輪播,滑鼠移出,開啟自動輪播
  overOut () {
      this.ele.addEventListener('mouseover', () => clearInterval(this.timer) )
      this.ele.addEventListener('mouseout', () => this.autoPlay())
  }
    // 使用者手動點選切換圖檔
  bindEvent () {
      this.ele.addEventListener('click',(e) => {
        // 簡單相容一下
        e = e || window.event
        // 擷取事件目标 并考慮相容
        const target = e.target ||e.srcElement
        // 判斷點選誰
        // 點選上一張,false 就是index--
        if (target.className === 'prev') this.changeOne(false)
        // 點選下一張, true 就是index++
        if (target.className === 'next') this.changeOne(true)
        // 點選某一張, 傳入該元素攜帶的自定義屬性值
        if (target.className === 'point') this.changeOne(target.dataset.i - 0)
      })
  }
}
// 調用
const b=new Banner('#banner')
           

繼續閱讀