利用jQuery實現圖片無限循環輪播(不借助於輪播插件)

原來我主要是用Bootstrap框架或者swiper插件實現輪播圖的功能,而此次是用jQuery來實現圖片無限循環輪播!javascript

用到的技術有:html、css、JavaScript(少)、jQuery(主要)css

效果展現:

html代碼:

<body>

<div id="container">
<!-- left:-600px 表示:頁面加載出現的第一張圖片是1.jp --> <div id="list" style="left: -600px;"> <img src="img/5.jpg" alt="5"/> <img src="img/1.jpg" alt="1"/> <img src="img/2.jpg" alt="2"/> <img src="img/3.jpg" alt="3"/> <img src="img/4.jpg" alt="4"/> <img src="img/5.jpg" alt="5"/> <img src="img/1.jpg" alt="1"/> </div> <div id="pointsDiv"> <span index="1" class="on"></span> <span index="2"></span> <span index="3"></span> <span index="4"></span> <span index="5"></span> </div> <a href="javascript:;" id="prev" class="arrow">&lt;</a> <a href="javascript:;" id="next" class="arrow">&gt;</a> </div> <script type="text/javascript" src="js/jquery-1.10.1.js"></script> <script type="text/javascript" src="js/app.js"></script> </body>

css代碼:

<style type="text/css">
    /*去除內邊距,沒有連接下劃線*/
    * {
      margin: 0;
      padding: 0;
      text-decoration: none;
    }

    /*讓body有20px的內邊距*/
    body {
      padding: 20px;
    }

    /*最外圍的div*/
    #container {
      width: 600px;
      height: 400px;
      overflow: hidden;
      position: relative; /*相對定位*/
      margin: 0 auto;
    }

    /*包含全部圖片的<div>*/

    #list {
      width: 4200px; /*7張圖片的寬: 7*600 */
      height: 400px;
      position: absolute; /*絕對定位*/
      z-index: 1;
    }

    /*全部的圖片<img> 的大小*/
    #list img {
      width: 600px;
      height: 400px;
      float: left; /*浮在左側*/
    }

    /*包含全部圓點按鈕的<div>*/
    #pointsDiv {
      position: absolute;
      height: 10px;
      width: 100px;
      z-index: 2;
      bottom: 20px;
      left: 250px;
    }

    /*全部的圓點<span>*/

    #pointsDiv span {
      cursor: pointer;
      float: left;
      border: 1px solid #fff;
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: #333;
      margin-right: 5px;
    }

    /*第一個<span>*/

    #pointsDiv .on {
      background: orangered;
    }

    /*切換圖標<a>*/

    .arrow {
      cursor: pointer;
      display: none;
      line-height: 39px;
      text-align: center;
      font-size: 36px;
      font-weight: bold;
      width: 40px;
      height: 40px;
      position: absolute;
      z-index: 2;
      top: 180px;
      background-color: RGBA(0, 0, 0, 0.3);
      color: #fff;
    }

    /*鼠標移到切換圖標上時*/
    .arrow:hover {
      background-color: RGBA(0, 0, 0, 0.7);
    }

    /*鼠標移到整個div區域時*/
    #container:hover .arrow {
      display: block; /*顯示*/
    }

    /*上一個切換圖標的左外邊距*/
    #prev {
      left: 20px;
    }

    /*下一個切換圖標的右外邊距*/
    #next {
      right: 20px;
    }
  </style>

jQuery代碼:

記,實現圖片輪播圖功能,能夠分爲6個步驟:html

1. 點擊向右的圖標, 平滑切換到下一頁;點擊向左的圖標, 平滑切換到上一頁。

(這步必定要想清楚,切換到上一頁,圖片向對於父元素朝右浮動一張圖片的寬度,因此left值爲正PAGE_WIDTH;同理,切換到下一頁,圖片向對於父元素朝左浮動一張圖片的寬度,因此left值爲負PAGE_WIDTH。java

其次,要仔細想一想「平緩切換」這一過程,咱們簡單的把點擊上一頁,圖片是瞬間向右移動的,咱們要怎麼作到平緩切換呢?jquery

舉個簡單的小例子,能夠幫助你理解:app

不知道你是否注意過在頁面點擊「回到頂點」時的滾動條滾動的樣子,滾動條不是一瞬間嗖的回到頂點的,而是有一個過程,這個過程就能夠看做一個「平緩」滾動。框架

那是如何作到的呢,分析一下this

滾動條距離頂點的距離,咱們能夠獲取總路程距離:var totalDistance = $(document.documentElement).scrollTop()+$(document.body).scrollTop();spa

而後咱們能夠定義回到頂點的總時間:var totalTime=1000;//1秒插件

再定義平緩滑動的每小段距離用的時間:var time = 50;

經過這三個參數,咱們能夠獲取小段路程距離的個數:var count = totalDistance/time;

獲取每小段的距離:var distance = totalDistance/count;

定義一個定時器,每次定時器運行時總距離減小distance距離,從而達到一個「平緩滑動」的視覺效果。

從這個小例子,咱們就能清晰的知道咱們只是把滑動的總距離分紅n個小距離,每小段距離都有一個時間間隔,從而給用戶一個「平緩滑動」的視覺效果而已。

因此「平緩切換」也是這樣實現的。

注:快速點擊時, 翻頁會出現bug,這是由於還在切換頁面中,就發生了點擊事件,而咱們每次設置圖片切換的總距離不變,可是事實上圖片到父元素的距離一直在改變

2. 無限循環切換: 第一頁的上一頁爲最後頁, 最後一頁的下一頁是第一頁

(這就是爲何html代碼裏面循環5張圖片,但html寫了7張圖片,這是爲了保證圖片能無限循環切換。

圖解:

代碼:

 //2. 無限循環切換: 第一頁的上一頁爲最後頁, 最後一頁的下一頁是第一頁
        // 若是到達了最右邊的圖片(1.jpg), 跳轉到最左邊的第2張圖片(1.jpg)
        if(currLeft===-(imgCount+1) * PAGE_WIDTH) {
          currLeft = -PAGE_WIDTH
        } else if(currLeft===0){
          // 若是到達了最左邊的圖片(5.jpg), 跳轉到最右邊的第2張圖片(5.jpg)
          currLeft = -imgCount * PAGE_WIDTH
        }

 

3. 每隔3s自動滑動到下一頁

4. 當鼠標進入圖片區域時, 自動切換中止, 當鼠標離開後,又開始自動切換

5. 切換頁面時, 下面的圓點也同步更新

6. 點擊圓點圖標切換到對應的頁

jQuery完整代碼:

$(function () {

  var $container = $('#container')
  var $list = $('#list')
  //圓點
  var $points = $('#pointsDiv>span')
  //向左
  var $prev = $('#prev')
  //向右
  var $next = $('#next')
  
  var PAGE_WIDTH = 600 //一頁的寬度
  var TIME = 400 // 翻頁的持續時間
  var ITEM_TIME = 20 // 單元移動的間隔時間
  var imgCount = $points.length
  var index = 0 //當前下標
  var moving = false // 標識是否正在翻頁(默認沒有)


  // 1. 點擊向右(左)的圖標, 平滑切換到下(上)一頁
  $next.click(function () {
      //點擊向右的圖標,切換到下一頁,list向左移動600px,即(相對於container)left:-600px
    nextPage(true)
  })
  $prev.click(function () {
    //點擊向左的圖標,切換到上一頁,list向右移動600px,即(相對於container)left:+600px
    nextPage(false)
  })

  // 3. 每隔3s自動滑動到下一頁
  var intervalId = setInterval(function () {
    nextPage(true)
  }, 3000)

  // 4. 當鼠標進入圖片區域時, 自動切換中止, 當鼠標離開後,又開始自動切換
  $container.hover(function () {
    // 清除定時器
    clearInterval(intervalId)
  }, function () {
    intervalId = setInterval(function () {
      nextPage(true)
    }, 3000)
  })

  // 6. 點擊圓點圖標切換到對應的頁
  //每一個圓點都加一個點擊監聽事件
  $points.click(function () {
    // 目標頁的下標
    var targetIndex = $(this).index()
    // 只有當點擊的不是當前頁的圓點時才翻頁
    if(targetIndex!=index) {
      nextPage(targetIndex)
    }
  })

  /**
   * 平滑翻頁
   * @param next
   * true: 下一頁
   * false: 上一頁
   * 數值: 指定下標頁
   */
  function nextPage (next) {
    /*
      總的時間: TIME=400
      單元移動的間隔時間: ITEM_TIME = 20
      總的偏移量: offset
      單元移動的偏移量: itemOffset = offset/(TIME/ITEM_TIME)

      啓動循環定時器不斷更新$list的left, 到達目標處中止中止定時器
     */

    //若是正在翻頁, 直接結束
    if(moving) { //已經正在翻頁中
      return
    }
    moving = true // 標識正在翻頁

    // 總的偏移量: offset
    var offset = 0
    // 計算offset
    if(typeof next==='boolean') {
      offset = next ? -PAGE_WIDTH : PAGE_WIDTH
    } else {
      offset = -(next-index)* PAGE_WIDTH
    }

    // 計算單元移動的偏移量: itemOffset
    var itemOffset = offset/(TIME/ITEM_TIME)
    // 獲得相對於父元素偏移量的left值
    var currLeft = $list.position().left
    // 計算出目標處的left值
    var targetLeft = currLeft + offset

    // 啓動循環定時器不斷更新$list的left, 到達目標處中止中止定時器
    var intervalId = setInterval(function () {
      // 計算出最新的currLeft
      currLeft += itemOffset
      if(currLeft===targetLeft) { // 到達目標位置
        // 清除定時器
        clearInterval(intervalId)

        // 標識翻頁中止
        moving = false

        //2. 無限循環切換: 第一頁的上一頁爲最後頁, 最後一頁的下一頁是第一頁
        // 若是到達了最右邊的圖片(1.jpg), 跳轉到最左邊的第2張圖片(1.jpg)
        if(currLeft===-(imgCount+1) * PAGE_WIDTH) {
          currLeft = -PAGE_WIDTH
        } else if(currLeft===0){
          // 若是到達了最左邊的圖片(5.jpg), 跳轉到最右邊的第2張圖片(5.jpg)
          currLeft = -imgCount * PAGE_WIDTH
        }

      }
      // 設置left
      $list.css('left', currLeft)
    }, ITEM_TIME)

    // 更新圓點
    updatePoints(next)
  }

  /**
   * 更新圓點
   * @param next
   */
  function updatePoints (next) {

    // 計算出目標圓點的下標targetIndex
    var targetIndex = 0
    if(typeof next === 'boolean') {
      if(next) {
        targetIndex = index + 1   // [0, imgCount-1]
        if(targetIndex===imgCount) {// 此時看到的是1.jpg-->第1個圓點
          targetIndex = 0
        }
      } else {
        targetIndex = index - 1
        if(targetIndex===-1) { // 此時看到的是5.jpg-->第5個圓點
          targetIndex = imgCount-1
        }
      }
    } else {
        //next表示點擊圓點的跳到的頁數
      targetIndex = next
    }

    // 將當前index的<span>的class移除
    // $points.eq(index).removeClass('on')
    $points[index].className = ''
    // 給目標圓點添加class='on'
    // $points.eq(targetIndex).addClass('on')
    $points[targetIndex].className = 'on'

    // 將index更新爲targetIndex
    index = targetIndex
  }
})
相關文章
相關標籤/搜索