成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

移動(dòng)端原生JS實(shí)現(xiàn)手指跟隨的觸控滑動(dòng)

時(shí)飛 / 1428人閱讀

摘要:為了模擬原生應(yīng)用的觸控效果,大量的應(yīng)用使用了手指跟隨的滑動(dòng)效果,也就是用手指滑動(dòng)幻燈片的效果,什么是手指跟隨如圖網(wǎng)上滑動(dòng)插件有不少,但好像沒一個(gè)好用的不是太多,就是不靈活這里用原生實(shí)現(xiàn)了該功能,不僅代碼量不多,邏輯也較簡(jiǎn)單。

為了模擬原生應(yīng)用的觸控效果,大量的“H5”應(yīng)用使用了手指跟隨的滑動(dòng)效果,也就是用手指滑動(dòng)幻燈片的效果, 什么是手指跟隨,如圖;

網(wǎng)上滑動(dòng)插件有不少,但好像沒一個(gè)好用的(不是bug太多,就是不靈活)這里用原生JS實(shí)現(xiàn)了該功能,不僅代碼量不多,邏輯也較簡(jiǎn)單。移動(dòng)端H5頁(yè)面的觸控觸發(fā)事件在我之前的一篇博客中寫了挺多.原博地址原生JS實(shí)現(xiàn)觸控滑動(dòng)(swipe)圖片輪播 (里面大致羅列了HTML5中touch事件的使用方法)

這里寫的PageSlide的使用的方法是將HTML結(jié)構(gòu)寫好后往里傳參就可以了.它接受所有滑動(dòng)頁(yè)面對(duì)象(在這里是document.querySelector("#pages") ) 和要設(shè)定的方向(用X,Y表示橫向或者縱向)以及一個(gè)可選的擴(kuò)展函數(shù).
DEMO在此(使用模擬器或者移動(dòng)設(shè)備打開預(yù)覽):
移動(dòng)端原生JS實(shí)現(xiàn)手指跟隨的觸控滑動(dòng)(縱向)
移動(dòng)端原生JS實(shí)現(xiàn)手指跟隨的觸控滑動(dòng)(橫向)

直接下載代碼出門左轉(zhuǎn)Github? PageSlideDemo

掃碼看DEMO(縱向):

這里將所有的代碼都封裝進(jìn)一個(gè)PageSlide的原型對(duì)象中,可以當(dāng)成原生JS插件來(lái)使用,它所要求的HTML的結(jié)構(gòu)為:

// 所有滑動(dòng)頁(yè)面的容器
content
//所有滑動(dòng)單頁(yè)
animation element
...

CSS樣式結(jié)構(gòu)為:

/* 注意加html標(biāo)簽,使得高度100%等于視窗高度 */
html,body{
  width:100%;
  height:100%;
  margin:0 ;
  padding:0 ;
  overflow:hidden; 
  ……
}

.pages{
    width: 100%;
    height: 100%;
    position: relative;
    ……
  
}
.page {
/*滑動(dòng)頁(yè)面的統(tǒng)一樣式 */
    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{……}
/* 所有動(dòng)畫使用類控制 */
.play .myAnimation {

...


}

要實(shí)現(xiàn)手指跟隨的滑動(dòng)效果, 關(guān)鍵在于通過touch事件來(lái)設(shè)置transform:translate3d(x,y,z)的參數(shù),并在滑動(dòng)結(jié)束(touchend)設(shè)置一個(gè)最小滑動(dòng)距離minRange,該距離范圍內(nèi)的滑動(dòng),translate3d的參數(shù)等于touchmove的滑動(dòng)距離,當(dāng)大于minRange時(shí), 則觸發(fā)下一頁(yè)(或上一頁(yè))的整體滑動(dòng),translate3d的X或Y的參數(shù)也就是視窗的寬(橫向滑動(dòng)時(shí))或者高(縱向滑動(dòng)時(shí))

另外,對(duì)于一個(gè)網(wǎng)頁(yè)app,還需要解決一個(gè)問題,即每個(gè)頁(yè)面中可能有動(dòng)畫或者其他的事件需要在該頁(yè)面出現(xiàn)時(shí)才開始播放,動(dòng)畫采用css類控制, 這里采用在每個(gè)當(dāng)前頁(yè)面中添加一個(gè).play的類作為標(biāo)記, 在每個(gè)頁(yè)面的CSS動(dòng)畫設(shè)置中,同樣加上.play類名,這樣就實(shí)現(xiàn)了當(dāng)頁(yè)面出現(xiàn)才開始播放本頁(yè)動(dòng)畫的功能。

PageSlide的代碼解析如下:

// PageSlide接收三個(gè)參數(shù):頁(yè)面元素,要設(shè)定的滑動(dòng)方向,可選的擴(kuò)展函數(shù)
var PageSlide = function(el, swipe, options) {
    this.options = options || {}  //可選函數(shù)
    this.current = 0  //當(dāng)前頁(yè)面索引
    this.pageX  //橫向的手指落點(diǎn)
    this.pageY   //縱向的手指落點(diǎn)
    this.height //設(shè)備高度
    this.width   //設(shè)備寬度
    this.flag  //判斷滑動(dòng)方向的變量
    this.move  //滑動(dòng)的距離

    this.$el = el //當(dāng)前頁(yè)面的對(duì)象
    this.swipe = swipe || "X" //滑動(dòng)方向參數(shù)
    this.resize().init().bindEvents() //初始化
}


PageSlide.prototype.init = function(i) {
    var current = i ? this.$el.children[i] : this.$el.firstElementChild
    if (!current) throw "ERROR";
//moving類名作為當(dāng)前滑動(dòng)頁(yè)面的標(biāo)記,也在樣式中作滑動(dòng)的擴(kuò)展效果
    current.classList.add("moving")
    current.style.webkitTransform = "translate3d(0,0,0)"
//以swipe的值預(yù)設(shè)置其他頁(yè)面的寬高,獲得流暢的交互效果
for(var i = 1; i  Math.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()
   //滑動(dòng)結(jié)束前往下一頁(yè)面,next()方法調(diào)用了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()
}

//動(dòng)態(tài)設(shè)定translate3d參數(shù)方法
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)")
}
//設(shè)置當(dāng)前觸控頁(yè)面translate3d參數(shù)為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]
    }

}
//調(diào)用go()方法前往下一或上一頁(yè)面
PageSlide.prototype.next = function() {
    this.go(this.current + 1)
}

PageSlide.prototype.prev = function() {
    this.go(this.current - 1)
}
//重置方法,用于初始化以及當(dāng)前頁(yè)面的重置
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))
}
//去往下一或上一頁(yè)面的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)
    // 滑動(dòng)完成調(diào)用方法
    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)
}
//滑動(dòng)完成后刪除當(dāng)前頁(yè)面.play標(biāo)記以及為下一頁(yè)面添加.play標(biāo)記
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 */ 
//直達(dá)某一頁(yè)面的方法, 因?yàn)橛袀€(gè)項(xiàng)目的需要,寫了這個(gè)方法,要從任意頁(yè)面開始滑動(dòng)依然能保持正常的滑動(dòng)體驗(yàn),就需要將直達(dá)頁(yè)面的前面所有頁(yè)面的translate3d參數(shù)都設(shè)置為(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
        
    
    }



總算寫完了,吃飯~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86019.html

相關(guān)文章

  • 把鼠標(biāo)、觸摸屏、觸控筆統(tǒng)一起來(lái),Pointer Events介紹

    摘要:把事件統(tǒng)一起來(lái)處理用戶的輸入要用到事件。就這樣,提取了鼠標(biāo)觸摸屏觸控筆的共通之處,以方便開發(fā)跨設(shè)備的應(yīng)用。雖然是一個(gè)抽象,但它包含了鼠標(biāo)觸摸屏觸控筆的全部?jī)?nèi)容。手指與觸摸屏的屏幕接觸著,認(rèn)定為。 跨設(shè)備的問題 平時(shí)我們?cè)陔娔X上訪問的網(wǎng)頁(yè),大部分情況下是用鼠標(biāo)來(lái)控制的。比如說(shuō)鏈接跳轉(zhuǎn),就是鼠標(biāo)指針移動(dòng)到鏈接文字或圖片的位置,然后點(diǎn)擊一下。又比如說(shuō)滾動(dòng)屏幕,滑動(dòng)一下鼠標(biāo)滾輪就可以。 如果是...

    FleyX 評(píng)論0 收藏0
  • 把鼠標(biāo)、觸摸屏、觸控筆統(tǒng)一起來(lái),Pointer Events介紹

    摘要:把事件統(tǒng)一起來(lái)處理用戶的輸入要用到事件。就這樣,提取了鼠標(biāo)觸摸屏觸控筆的共通之處,以方便開發(fā)跨設(shè)備的應(yīng)用。雖然是一個(gè)抽象,但它包含了鼠標(biāo)觸摸屏觸控筆的全部?jī)?nèi)容。手指與觸摸屏的屏幕接觸著,認(rèn)定為。 跨設(shè)備的問題 平時(shí)我們?cè)陔娔X上訪問的網(wǎng)頁(yè),大部分情況下是用鼠標(biāo)來(lái)控制的。比如說(shuō)鏈接跳轉(zhuǎn),就是鼠標(biāo)指針移動(dòng)到鏈接文字或圖片的位置,然后點(diǎn)擊一下。又比如說(shuō)滾動(dòng)屏幕,滑動(dòng)一下鼠標(biāo)滾輪就可以。 如果是...

    elarity 評(píng)論0 收藏0
  • 從零搭建移動(dòng)H5開發(fā)項(xiàng)目實(shí)戰(zhàn)

    摘要:并且除了常用的端,還要考慮微信端,或者是端。所以我們要有一套機(jī)制,在端上走的代碼,在端或者微信端上走端對(duì)應(yīng)的代碼。對(duì)于一個(gè)從零開始的移動(dòng)端項(xiàng)目,我總結(jié)了以上這些移動(dòng)開發(fā)難點(diǎn),希望之后的人能少踩點(diǎn)坑,站在我的肩膀上提高項(xiàng)目開發(fā)的效率和質(zhì)量。 從零搭建移動(dòng)H5開發(fā)項(xiàng)目實(shí)戰(zhàn) 前端H5的前世今身 在Pc的時(shí)代,前端技術(shù)無(wú)疑統(tǒng)治了大多數(shù)用戶的交互界面!而在移動(dòng)為王的今天,NA開發(fā)在早期占領(lǐng)了大多...

    terro 評(píng)論0 收藏0
  • 從零搭建移動(dòng)H5開發(fā)項(xiàng)目實(shí)戰(zhàn)

    摘要:并且除了常用的端,還要考慮微信端,或者是端。所以我們要有一套機(jī)制,在端上走的代碼,在端或者微信端上走端對(duì)應(yīng)的代碼。對(duì)于一個(gè)從零開始的移動(dòng)端項(xiàng)目,我總結(jié)了以上這些移動(dòng)開發(fā)難點(diǎn),希望之后的人能少踩點(diǎn)坑,站在我的肩膀上提高項(xiàng)目開發(fā)的效率和質(zhì)量。 從零搭建移動(dòng)H5開發(fā)項(xiàng)目實(shí)戰(zhàn) 前端H5的前世今身 在Pc的時(shí)代,前端技術(shù)無(wú)疑統(tǒng)治了大多數(shù)用戶的交互界面!而在移動(dòng)為王的今天,NA開發(fā)在早期占領(lǐng)了大多...

    pepperwang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<