如何用H5實現一個觸屏版的輪播器?
初入前端,分享一下手機上觸屏版輪播器的實現過程,大致功能如下:
支援迴圈滑動
寬度可任意設定,不需要與螢幕等寬
頁面可縱向滾動
可設定回撥監聽元素的切換
純js,不借助任何第三方庫
原理
假設子元素
.item
的width
為375px,使用絕對定位將所有子元素放在父元素內將父元素
.carousel
的width
設定為375px,與子元素.item
寬度相同為父元素
.carousel
新增觸控事件:touchstart
,touchmove
,touchend
手指按下時,儲存初始位置(
clientX
)手指滑動時,透過滑動距離判斷滑動的方向:
手指向左滑動,則同時移動當前元素和當前元素右邊的元素
手指向右滑動,則同時移動當前元素和當前元素左邊的元素
手指抬起時,透過滑動距離判斷是否切換到下一頁
移動距離未超過子元素寬度的50%,將當前頁面回滾到初始位置,不切換當前元素。
移動距離超過子元素寬度的50%,切換當前元素為下一個元素。
將當前元素的
transform
屬性設定為translate3d(0px, 0px, 0px)
,並將z-index
屬性+1將下一個子元素的
transform
屬性設定為translate3d(375px, 0px, 0px)
,並將z-index
屬性+1將上一個子元素的
transform
屬性設定為translate3d(-375px, 0px, 0px)
,並將z-index
屬性+1將其他所有子元素的
z-index
屬性設定為預設值第一個子元素的上一個元素是最後一個元素,最後一個元素的下一個元素是第一個元素,該步驟透過迴圈連結串列實現。
移動時設定的是子元素.item的transform屬性,而不是父元素
.carousel
實現步驟
html&css
//html//css .carousel{ height: 50%; position: relative; overflow: hidden; } .item { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }item-1
item-2
item-3
item-4
item-5
js
設定初始狀態
首先實現一個雙向連結串列,用於維護輪播元件中的元素。
function Node(data) { this.data = data; this.prev = null; this.next = null; this.index = -1; }//雙向迴圈列表function LinkList() { var _nodes = []; this.head = null; this.last = null; if (typeof this.append !== "function") { LinkList.prototype.append = function (node) { if (this.head == null) { this.head = node; this.last = this.head; } else { this.head.prev = node; this.last.next = node; node.prev = this.last; node.next = this.head; this.last = node; } node.index = _nodes.length; //務必在push前設定node.index _nodes.push(node); } } }
有了連結串列之後,建立一個連結串列例項,將子元素新增進連結串列內,並設定一些初始狀態
var _container = document.querySelector("." + containerClass);var _items = document.querySelectorAll("." + itemClass);var list = loop ? new LinkList() : new SingleList();for(var i = 0; i繫結觸控事件
touchstart事件
手指按下時,儲存初始位置
_container.addEventListener("touchstart", function(e) { // e.preventDefault();//取消此行程式碼的註釋會在該元素內阻止頁面縱向滾動 var touch = e.touches[0]; startX = touch.clientX; //儲存手指按下時的位置 startY = touch.clientY; _container.style.webkitTransition = ""; //取消動畫效果 startT = new Date().getTime(); //記錄手指按下的開始時間 isMove = false; transitionItems(_prev, false); //取消之前元素的過渡 transitionItems(_current, false); //取消當前元素的過渡}, false);touchmove事件
手指在螢幕上滑動,頁面跟隨手指移動
_container.addEventListener("touchmove", function(e) { // e.preventDefault();//取消此行程式碼的註釋會在該元素內阻止頁面縱向滾動 var touch = e.touches[0]; var deltaX = touch.clientX - startX; //計算手指在X方向滑動的距離 var deltaY = touch.clientY - startY; //計算手指在Y方向滑動的距離 //如果X方向上的位移大於Y方向,則認為是左右滑動 if (Math.abs(deltaX) > Math.abs(deltaY)){ translate = deltaX > _itemWidth ? _itemWidth : deltaX; translate = deltaXtouchend事件
手指離開螢幕時,計算最終需要停留在哪一頁
_container.addEventListener("touchend",function(e) { // e.preventDefault();//取消此行程式碼的註釋會在該元素內阻止頁面縱向滾動 //是否會滾 var isRollback = false; //計算手指在螢幕上停留的時間 var deltaT = new Date().getTime() - startT; if (isMove) { //發生了左右滑動 //如果停留時間小於300ms,則認為是快速滑動,無論滑動距離是多少,都停留到下一頁 if(deltaTCarousel庫
為了方便使用,我將整個實現過程封裝成了一個庫,並新增了
prev()
,next()
方法,使用非常簡單:該庫可到github
參考
good night!
作者:gongzhen
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3137/viewspace-2812910/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用 React 實現一個輪播元件React元件
- 教你如何用 RecyclerView 做一個好用的輪播圖View
- 在 Flutter 中實現一個無限輪播Flutter
- 如何快速實現一個無縫輪播效果
- 原生 JS 擼一個輪播圖(支援拖拽切屏)JS
- 一個基於Vue的圖片輪播元件的實現Vue元件
- 用原生js實現圖片輪播器JS
- 用RecyclerView打造一個輪播圖(進階版)View
- 高效圖片輪播,兩個ImageView實現View
- Axure實現輪播效果
- ViewPage實現輪播圖View
- Banner實現輪播圖
- js實現輪播圖JS
- jQuery實現輪播效果jQuery
- 如何用Phaser實現一個全家福拼圖H5H5
- Bootstrap教程(26)–輪播的實現boot
- Vue之網易雲音樂PC版輪播圖的實現Vue
- css實現滾動輪播CSS
- 原生js實現輪播圖JS
- 圖片輪播元件實現元件
- Vue專案中使用better-scroll實現一個輪播圖Vue
- 原生JS實現一個無縫輪播圖外掛(支援vue)JSVue
- vue元件之輪播圖的實現Vue元件
- 原生JS實現輪播圖的效果JS
- 左右無縫輪播圖的實現
- 直播平臺原始碼,數字化大屏地圖輪播的實現echarts原始碼地圖Echarts
- 利用輪播原理結合hammer.js實現簡潔的滑屏功能JS
- 如何用物件導向的思維去封裝一個小型輪播圖外掛物件封裝
- xbanner實現卡片式輪播
- 兩種方式實現輪播圖
- (轉)jquery實現圖片輪播jQuery
- vue元件之路之輪播圖的實現Vue元件
- 用RecyclerView打造一個輪播圖View
- 請問如何用多執行緒實現一個輪詢功能?謝謝!執行緒
- better-scroll 實現無縫輪播
- [分享會]只用CSS實現輪播圖CSS
- 使用jQuery實現的平滑滾動輪播圖jQuery
- 仿小米官網輪播圖(Banner)的實現