原生JS實現觸控滑動(swipe)圖片輪播

上週寫了段圖片自動輪播的代碼,感受應用的侷限性仍是挺大,實習期間一直在搗鼓移動端網頁的開發,這周試了試原生JS實現左右滑動的圖片輪播,在網上找了不少滑動插件諸如swipe,hammer,Quo,JQM 用着都不太理想, 最後一咬牙仍是本身碼,先上DEMO, 用手機打開demo查看效果或用Chrome模擬(在iPhone上測試沒有問題,可是安卓上彷佛有時會有卡頓,不知道是我手機的問題仍是代碼兼容性有問題,還有待測試)。
原生JS實現觸控滑動(swipe)圖片輪播DEMOhtml

左右觸控的動做識別關鍵在於HTML5的touch事件中手指座標的偏移量,判斷touchmove與touchstart之間手指(touchs)的位置偏移便可判斷出是左滑(偏移爲正)仍是右滑(偏移爲負),淡入淡出的方法實現仍是用我以前使用的CSS3 transition 詳情可見我上篇博客:
基於CSS3實現淡入(fadeIn)淡出(fadeOut)效果
本文只是簡單的使用了html5的touch API , 利用touch事件實現更復雜的交互(好比相似幻燈片或者原生應用的手指跟隨的翻頁效果可看我這篇博客:移動端原生JS實現手指跟隨的觸控滑動
話休絮煩上代碼:html5

HTMLweb

<!-- images box --!>
<div id="imgs">
  <div id="bg1" class="bg"></div>
  <div id="bg2" class="bg"></div>
  <div id="bg3" class="bg"></div>
  <div id="bg4" class="bg"></div>
  <div id="bg5" class="bg"> </div>
</div>
<!-- ths pagination box --!>
<div class="pagination-panel">
  <ul class="pagination">
    <li id="dot_0" class="page-dot"></li>
    <li id="dot_1" class="page-dot"></li>
    <li id="dot_2" class="page-dot"></li>
    <li id="dot_3" class="page-dot"></li>
    <li id="dot_4" class="page-dot"></li>
  </ul>
</div>

CSS:segmentfault

.bg {
    position: absolute;
    left: 0;
    top: 0;
    width: 100vw;
    height: 100vh;
    -webkit-transition: opacity .9s linear;
    -moz-transition: opacity .9s linear;
    -o-transition: opacity .9s linear;
    transition: opacity .9s linear;
    opacity:0;
    filter: alpha(opacity=0);
}
#bg1 {
    background: url(http://i3.tietuku.com/6c65325bbf87eb84.jpg) no-repeat;
            background-size: cover;    
}
#bg2 {
    background: url(http://i3.tietuku.com/a72ff6249b76a87e.jpg) no-repeat;
            background-size: cover;    
}
#bg3 {
    background: url(http://i3.tietuku.com/eba2fb18598fa5ca.jpg) no-repeat;
            background-size: cover;
    }
#bg4 {
    background: url(http://i3.tietuku.com/780c4c17e7bcc81d.jpg) no-repeat;
            background-size: cover;
}
#bg5 {
    background: url(http://i3.tietuku.com/8f4305f8f9538037.jpg) no-repeat;
            background-size: cover;
}
.fadein {
    opacity: 100;
    filter: alpha(opacity=100);
}
.pagination {
    width: auto;
    display: table;
    margin: 0 auto
}
.pagination-panel {
    width: 100%;
    position: fixed;
    bottom: 50px;
    z-index: 100;
    height: auto
}
.pagination li {
    border-radius: 15px;
    height: 15px;
    width: 15px;
    background: #fff;
    float: left;
    margin-right: 10px;
    list-style-type: none
}

.pagination li.active {
    background: #52c6d8
}
.pagination li:last-child {
    margin-right: 0
}

JS:ide

//封裝的對象接受全部圖片的盒元素與觸發切換的最小滑動距離做爲參數
var ImageSwiper = function(imgs, minRange) {
  this.imgBox = imgs
  this.imgs = imgs.children
  this.cur_img = 1  //起始圖片設爲1 ,而非0,將在圖片顯示方法中做-1處理
  this.ready_moved = true  //判斷每次滑動開始的標記變量
  this.imgs_count = this.imgs.length
  this.touchX  //觸控開始的手指最初落點
  this.minRange = Number(minRange)
  this.fadeIn  //圖片切換的方式,這裏使用淡入淡出
  this.fadeOut
  this.bindTouchEvn() //初始化綁定滑動事件
  this.showPic(this.cur_img) //顯示圖片方法,注意其中圖片編號的-1處理
}
ImageSwiper.prototype.bindTouchEvn = function() {
  this.imgBox.addEventListener('touchstart', this.touchstart.bind(this), false)
  this.imgBox.addEventListener('touchmove', this.touchmove.bind(this), false)
  this.imgBox.addEventListener('touchend', this.touchend.bind(this), false)
    
}
ImageSwiper.prototype.touchstart = function(e) {
  if (this.ready_moved) {
    var touch = e.touches[0];
    this.touchX = touch.pageX;
    this.ready_moved = false;

  }

}

ImageSwiper.prototype.touchmove = function(e) {
  e.preventDefault();
  var minRange = this.minRange
  var touchX = this.touchX
  var imgs_count = this.imgs_count

  if (!this.ready_moved) {

    var release = e.changedTouches[0];
    var releasedAt = release.pageX;
    if (releasedAt + minRange < touchX) {
      this.ready_moved = true;
      if (this.cur_img > (imgs_count - 1)) {
        this.cur_img = 0;
      }
      this.cur_img++;
      this.showPic(this.cur_img);

    } else if (releasedAt - minRange > touchX) {
      if (this.cur_img <= 1) {
        this.cur_img = imgs_count + 1
      }
      this.cur_img--;
      this.showPic(this.cur_img);
      this.ready_moved = true;
    }
  }

}

ImageSwiper.prototype.touchend = function(e) {
  e.preventDefault();
  var minRange = this.minRange
  var touchX = this.touchX
  var imgs_count = this.imgs_count
  if (!this.ready_moved) {
    var release = e.changedTouches[0];
    var releasedAt = release.pageX;
    if (releasedAt + minRange < touchX) {
      this.ready_moved = true;
      if (this.cur_img > (imgs_count - 1)) {
        this.cur_img = 0;
      }
      this.cur_img++;
      showPic(this.cur_img);

    } else if (releasedAt - minRange > touchX) {
      if (this.cur_img <= 1) {
        this.cur_img = imgs_count + 1
      }
      this.cur_img--;
      showPic(this.cur_img);
      this.ready_moved = true;
    }
  }

}
//在樣式表中設置好 .fadeIn 的透明度爲0
ImageSwiper.prototype.fadeIn = function(e) {
  e.classList.add("fadeIn")
}

ImageSwiper.prototype.fadeOut = function(e) {
  Array.prototype.forEach.call(e, function(e) {
    e.className = "bg"
  })
}

ImageSwiper.prototype.showPic = function(cur_img) {
  this.hidePics(this.imgs)
//獲得圖片元素的真實索引
  var index = cur_img - 1

  if (document.getElementsByClassName("active")[0]) {
    var active = document.getElementsByClassName("active")[0];
    active.classList.remove("active")
  }
  console.log(this.cur_img)
  document.getElementById("dot_" + index).classList.add("active");

  this.fadeIn(this.imgs[index]);

}
ImageSwiper.prototype.hidePics = function(e) {
  this.fadeOut(e)

}
//傳參
var imgs = new ImageSwiper(document.getElementById('imgs'), 30)
相關文章
相關標籤/搜索