摘要:為了模擬原生應用的觸控效果,大量的應用使用了手指跟隨的滑動效果,也就是用手指滑動幻燈片的效果,什么是手指跟隨如圖網上滑動插件有不少,但好像沒一個好用的不是太多,就是不靈活這里用原生實現了該功能,不僅代碼量不多,邏輯也較簡單。
為了模擬原生應用的觸控效果,大量的“H5”應用使用了手指跟隨的滑動效果,也就是用手指滑動幻燈片的效果, 什么是手指跟隨,如圖;
網上滑動插件有不少,但好像沒一個好用的(不是bug太多,就是不靈活)這里用原生JS實現了該功能,不僅代碼量不多,邏輯也較簡單。移動端H5頁面的觸控觸發事件在我之前的一篇博客中寫了挺多.原博地址原生JS實現觸控滑動(swipe)圖片輪播 (里面大致羅列了HTML5中touch事件的使用方法)
這里寫的PageSlide的使用的方法是將HTML結構寫好后往里傳參就可以了.它接受所有滑動頁面對象(在這里是document.querySelector("#pages") ) 和要設定的方向(用X,Y表示橫向或者縱向)以及一個可選的擴展函數.
DEMO在此(使用模擬器或者移動設備打開預覽):
移動端原生JS實現手指跟隨的觸控滑動(縱向)
移動端原生JS實現手指跟隨的觸控滑動(橫向)
直接下載代碼出門左轉Github? PageSlideDemo
掃碼看DEMO(縱向):
這里將所有的代碼都封裝進一個PageSlide的原型對象中,可以當成原生JS插件來使用,它所要求的HTML的結構為:
// 所有滑動頁面的容器content//所有滑動單頁...animation element
CSS樣式結構為:
/* 注意加html標簽,使得高度100%等于視窗高度 */ html,body{ width:100%; height:100%; margin:0 ; padding:0 ; overflow:hidden; …… } .pages{ width: 100%; height: 100%; position: relative; …… } .page { /*滑動頁面的統一樣式 */ position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; transform: translate3d(0px, 100%, 0px); -webkit-transform: translate3d(0px, 100%, 0px); transition: transform .5s ease-out; -webkit-transition: -webkit-transform .5s ease-out; } .page1{……} .page2{……} .page3{……} /* 所有動畫使用類控制 */ .play .myAnimation { ... }
要實現手指跟隨的滑動效果, 關鍵在于通過touch事件來設置transform:translate3d(x,y,z)的參數,并在滑動結束(touchend)設置一個最小滑動距離minRange,該距離范圍內的滑動,translate3d的參數等于touchmove的滑動距離,當大于minRange時, 則觸發下一頁(或上一頁)的整體滑動,translate3d的X或Y的參數也就是視窗的寬(橫向滑動時)或者高(縱向滑動時)
另外,對于一個網頁app,還需要解決一個問題,即每個頁面中可能有動畫或者其他的事件需要在該頁面出現時才開始播放,動畫采用css類控制, 這里采用在每個當前頁面中添加一個.play的類作為標記, 在每個頁面的CSS動畫設置中,同樣加上.play類名,這樣就實現了當頁面出現才開始播放本頁動畫的功能。
PageSlide的代碼解析如下:
// PageSlide接收三個參數:頁面元素,要設定的滑動方向,可選的擴展函數 var PageSlide = function(el, swipe, options) { this.options = options || {} //可選函數 this.current = 0 //當前頁面索引 this.pageX //橫向的手指落點 this.pageY //縱向的手指落點 this.height //設備高度 this.width //設備寬度 this.flag //判斷滑動方向的變量 this.move //滑動的距離 this.$el = el //當前頁面的對象 this.swipe = swipe || "X" //滑動方向參數 this.resize().init().bindEvents() //初始化 } PageSlide.prototype.init = function(i) { var current = i ? this.$el.children[i] : this.$el.firstElementChild if (!current) throw "ERROR"; //moving類名作為當前滑動頁面的標記,也在樣式中作滑動的擴展效果 current.classList.add("moving") current.style.webkitTransform = "translate3d(0,0,0)" //以swipe的值預設置其他頁面的寬高,獲得流暢的交互效果 for(var i = 1; iMath.abs(Y) ? "X" : "Y" if (this.flag === this.swipe) { current.classList.add("moving") next && next.classList.add("moving") prev && prev.classList.add("moving") } } if (this.flag === this.swipe) { e.preventDefault() e.stopPropagation() switch (this.swipe) { case "X": //swipe horizontal this.move = X this.setX(current, X) next && (this.setX(next, X + this.width)) prev && (this.setX(prev, X - this.width)) break; case "Y": //swipe vertical this.move = Y this.setY(current, Y) next && (this.setY(next, Y + this.height)) prev && (this.setY(prev, Y - this.height)) break; } } } PageSlide.prototype.touchend = function(e) { var minRange = 50 var move = this.move var current = this.getCurrent() var next = current.nextElementSibling var prev = current.previousElementSibling current.classList.remove("moving") next && next.classList.remove("moving") prev && prev.classList.remove("moving") if (!this.flag) return e.preventDefault() //滑動結束前往下一頁面,next()方法調用了go()方法 if (move < -minRange && next) return this.next() if (move > minRange && prev) return this.prev() this.reset() } PageSlide.prototype.touchcancel = function(e) { var current = this.getCurrent() var next = current.nextElementSibling var prev = current.previousElementSibling current.classList.remove("moving") next && next.classList.remove("moving") prev && prev.classList.remove("moving") this.reset() } //動態設定translate3d參數方法 PageSlide.prototype.setX = function(el, x, unit) { el && (el.style.webkitTransform = "translate3d(" + x + (unit || "px") + ",0,0)") } PageSlide.prototype.setY = function(el, y, unit) { el && (el.style.webkitTransform = "translate3d(0," + y + (unit || "px") + ",0)") } //設置當前觸控頁面translate3d參數為0的方法 PageSlide.prototype.setCurrent = function(el, i) { el && (el.style.webkitTransform = "translate3d(0,0,0)") if (i) { this.current = i this.$current = this.$el.children[i] } } //調用go()方法前往下一或上一頁面 PageSlide.prototype.next = function() { this.go(this.current + 1) } PageSlide.prototype.prev = function() { this.go(this.current - 1) } //重置方法,用于初始化以及當前頁面的重置 PageSlide.prototype.reset = function() { var width = this.width var height = this.height var swipe = this.swipe var current = this.getCurrent() var prev = current.previousElementSibling var next = current.nextElementSibling this.setCurrent(current) prev && (this["set" + swipe](prev, -(swipe === "X" ? width : height))) next && (this["set" + swipe](next, swipe === "X" ? width : height)) } //去往下一或上一頁面的go方法 PageSlide.prototype.go = function(i) { var onFinish = this.options.onFinish var current = this.getCurrent() var total = this.$el.childElementCount var target = this.$el.children[i] var d = i < this.current ? -1 : 1 if (i === this.current || i < 0 || i >= total) return if (onFinish && (typeof onFinish === "function")) onFinish.call(this, i) // 滑動完成調用方法 typeof this.options.tranSetionEnd ==="function" && this.options.tranSetionEnd.call(this) this.current = i this["set" + this.swipe](current, -d * (this.swipe === "X" ? this.width : this.height)) this.setCurrent(target, i) this.finish(current, target) } //滑動完成后刪除當前頁面.play標記以及為下一頁面添加.play標記 PageSlide.prototype.finish = function(curr, target) { this.flag = null setTimeout(function() { curr && curr.classList.remove("play") target && target.classList.add("play") }, 3e2) } /*direct to a page */ //直達某一頁面的方法, 因為有個項目的需要,寫了這個方法,要從任意頁面開始滑動依然能保持正常的滑動體驗,就需要將直達頁面的前面所有頁面的translate3d參數都設置為(0,-height,0) PageSlide.prototype.direct = function(i){ if(i&&typeof(i)==="number") { this.go(i) for(var j = 0; j< i ;j++) { this["set" + this.swipe](this.$el.children[j], -1 * (this.swipe === "X" ? this.width : this.height)) } } else return }
總算寫完了,吃飯~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86019.html
摘要:把事件統一起來處理用戶的輸入要用到事件。就這樣,提取了鼠標觸摸屏觸控筆的共通之處,以方便開發跨設備的應用。雖然是一個抽象,但它包含了鼠標觸摸屏觸控筆的全部內容。手指與觸摸屏的屏幕接觸著,認定為。 跨設備的問題 平時我們在電腦上訪問的網頁,大部分情況下是用鼠標來控制的。比如說鏈接跳轉,就是鼠標指針移動到鏈接文字或圖片的位置,然后點擊一下。又比如說滾動屏幕,滑動一下鼠標滾輪就可以。 如果是...
摘要:把事件統一起來處理用戶的輸入要用到事件。就這樣,提取了鼠標觸摸屏觸控筆的共通之處,以方便開發跨設備的應用。雖然是一個抽象,但它包含了鼠標觸摸屏觸控筆的全部內容。手指與觸摸屏的屏幕接觸著,認定為。 跨設備的問題 平時我們在電腦上訪問的網頁,大部分情況下是用鼠標來控制的。比如說鏈接跳轉,就是鼠標指針移動到鏈接文字或圖片的位置,然后點擊一下。又比如說滾動屏幕,滑動一下鼠標滾輪就可以。 如果是...
摘要:并且除了常用的端,還要考慮微信端,或者是端。所以我們要有一套機制,在端上走的代碼,在端或者微信端上走端對應的代碼。對于一個從零開始的移動端項目,我總結了以上這些移動開發難點,希望之后的人能少踩點坑,站在我的肩膀上提高項目開發的效率和質量。 從零搭建移動H5開發項目實戰 前端H5的前世今身 在Pc的時代,前端技術無疑統治了大多數用戶的交互界面!而在移動為王的今天,NA開發在早期占領了大多...
摘要:并且除了常用的端,還要考慮微信端,或者是端。所以我們要有一套機制,在端上走的代碼,在端或者微信端上走端對應的代碼。對于一個從零開始的移動端項目,我總結了以上這些移動開發難點,希望之后的人能少踩點坑,站在我的肩膀上提高項目開發的效率和質量。 從零搭建移動H5開發項目實戰 前端H5的前世今身 在Pc的時代,前端技術無疑統治了大多數用戶的交互界面!而在移動為王的今天,NA開發在早期占領了大多...
閱讀 834·2021-09-22 15:18
閱讀 1184·2021-09-09 09:33
閱讀 2759·2019-08-30 10:56
閱讀 1194·2019-08-29 16:30
閱讀 1493·2019-08-29 13:02
閱讀 1463·2019-08-26 13:55
閱讀 1648·2019-08-26 13:41
閱讀 1945·2019-08-26 11:56