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

資訊專欄INFORMATION COLUMN

JS實現(xiàn)一個scroll自定義滾動效果

WalkerXu / 3519人閱讀

摘要:實現(xiàn)一個自定義滾動效果在公司開發(fā)項目的時候,原生滾動條中有些東西沒辦法自定義去精細的控制,于是開發(fā)一個類似于一樣的瀏覽器滾動監(jiān)聽的實現(xiàn),下面我們就來探究一下自定義滾動需要考慮哪些東西,經(jīng)過哪些過程。

JS實現(xiàn)一個scroll自定義滾動效果

在公司開發(fā)項目的時候,原生滾動條中有些東西沒辦法自定義去精細的控制,于是開發(fā)一個類似于better-scroll一樣的瀏覽器滾動監(jiān)聽的JS實現(xiàn),下面我們就來探究一下自定義滾動需要考慮哪些東西,經(jīng)過哪些過程。

選擇滾動監(jiān)聽的事件

因為是自定義手機端的滾動事件,那我選擇的是監(jiān)聽手機端的三個touch事件來實現(xiàn)監(jiān)聽,并實現(xiàn)了兩種滾動效果,一種是通過-webkit-transform,一種是通過top屬性。兩種實現(xiàn)對于滾動的基本效果夠能達到,可是top的不適合滾動中還存在滾動,可是能解決滾動中存在postion:fixed屬性的問題;而transform可以實現(xiàn)滾動中有滾動,可是又不能解決postion:fixed的問題,所以,最后選擇性考慮使用哪一種實現(xiàn)方式,用法一樣。

主要的實現(xiàn)業(yè)務邏輯
handleTouchMove(event){
    event.preventDefault();
    this.currentY = event.targetTouches[0].screenY;
    this.currentTime = new Date().getTime();
    // 二次及以上次數(shù)滾動(間歇性滾動)時間和路程重置計算,0.05是間歇性滾動的停頓位移和時間比
    if (Math.abs(this.currentY - this.lastY) / Math.abs(this.currentTime - this.lastTime) < 0.05) {
        this.startTime = new Date().getTime();
        this.resetY = this.currentY;
    }
    this.distance = this.currentY - this.startY;
    let temDis = this.distance + this.oldY;
    /*設置移動最小值*/
    temDis = temDis > this.minValue ? temDis * 1 / 3 : temDis;
    /*設置移動最大值*/
    temDis = temDis < -this.maxValue ? -this.maxValue + (temDis + this.maxValue) * 1 / 3 : temDis;
    this.$el.style["top"] = temDis + "px";
    this.lastY = this.currentY;
    this.lastTime = this.currentTime;
    this.dispatchEvent();
    this.scrollFunc(event);
},

代碼解讀:這是監(jiān)聽touchmove事件的回調(diào),其中主要計算出目標節(jié)點this.$eltop或者-webkit-transform中translateY的值,而計算的參考主要以事件節(jié)點的screenY的垂直移動距離為參考,當然其中還要判斷一下最大值和最小值,為了保證移動可以的超出最大值小值一定的距離所以加了一個1/3的移動計算。這里可能主要到了有一個間歇性滾動的判斷和計算,主要是服務于慣性滾動的,目的是讓慣性滾動的值更加精確。

handleTouchEnd(event){
    /*點透事件允許通過*/
    if (!this.distance) return;
    event.preventDefault();
    let temDis = this.distance + this.oldY;
    /*計算緩動值*/
    temDis = this.computeSlowMotion(temDis);
    /*設置最小值*/
    temDis = temDis > this.minValue ? this.minValue : temDis;
    /*設置最大值*/
    temDis = temDis < -this.maxValue ? -this.maxValue : temDis;
    this.$el.style["transitionDuration"] = "500ms";
    this.$el.style["transitionTimingFunction"] = "ease-out";
    /*確定最終的滾動位置*/
    setTimeout(()=> {
        this.$el.style["top"] = temDis + "px";
    }, 0);
    // 判斷使用哪一種監(jiān)聽事件
    if (this.slowMotionFlag) {
        this.dispatchEventLoop();
    } else {
        this.dispatchEvent();
    }
    this.$el.addEventListener("transitionend", ()=> {
        window.cancelAnimationFrame(this.timer);
    });
    this.scrollFunc(event);
}

代碼解讀:這是touchend事件監(jiān)聽的回調(diào),其中這里要判斷是否要攔截click和tap事件,并且這里還要計算慣性緩動值,設置最終的最大最小值,以及設置動畫效果和緩動效果。下面來談一下滾性滾動的計算:

// 計算慣性滾動值
computeSlowMotion(temDis){
    var duration = new Date().getTime() - this.startTime;
    // 300毫秒是判斷間隔的最佳時間
    var resetDistance = this.currentY - this.resetY;
    if (duration < 300 && Math.abs(resetDistance) > 10) {
        var speed = Math.abs(resetDistance) / duration,
            destination;
        // 末速度為0 距離等于初速度的平方除以2倍加速度
        destination = (speed * speed) / (2 * this.deceleration) * (resetDistance < 0 ? -1 : 1);
        this.slowMotionFlag = true;
        return temDis += destination;
    } else {
        this.slowMotionFlag = false;
        return temDis;
    }
},

代碼解讀:滾性滾動的算法主要是根據(jù)一個路程和時間計算出初速度,以及原生滾動的加速度的大于值0.006來計算滾動的總位移。這里主要還要判斷一下一個300ms的經(jīng)驗值。

總結(jié)

大概的流程和思考就是這樣了,后續(xù)還會增加更多的功能進行擴展,下面附上git地址:https://github.com/yejiaming/scroll

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

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

相關文章

  • javascript模塊化(二)--RequireJS初探

    摘要:看完視頻初步認識了一下,以及模塊化開發(fā)的概念,在此做一下總結(jié)。所以應該將功能抽象成模塊。并且非常耗性能解決辦法,在滾動條正在運動或者已經(jīng)到達目的地,就不應該執(zhí)行動畫。 前言:在慕課網(wǎng)上跟著視頻《側(cè)邊工具欄開發(fā)》做了一遍,用到了jquery操作DOM,其中,用requirejs管理模塊依賴,然后自定義了兩個模塊它們都依賴jquery,并且其中一個自定義模塊依賴另一個,所以要暴露出接口???..

    edgardeng 評論0 收藏0
  • 移動端實現(xiàn)內(nèi)滾動的4種方案

    摘要:部分區(qū)域固定其余區(qū)域滾動部分區(qū)域固定為頁面的部分設置以及,即禁用頁面原生的滾動,保證只會顯示一屏的內(nèi)容。但是單位對低版本安卓和支持不夠好,微信瀏覽器內(nèi)核不支持,雖然已經(jīng)升級到內(nèi)核,但是為了確保萬無一失,放棄采用這種方案。 如果在一個區(qū)域內(nèi)只允許部分區(qū)域產(chǎn)生滾動的效果,而其余部分不能移動,你會采用什么方法呢? 作者:Icarus原文鏈接:http://xdlrt.github.io/20...

    CodeSheep 評論0 收藏0
  • 移動端實現(xiàn)內(nèi)滾動的4種方案

    摘要:部分區(qū)域固定其余區(qū)域滾動部分區(qū)域固定為頁面的部分設置以及,即禁用頁面原生的滾動,保證只會顯示一屏的內(nèi)容。但是單位對低版本安卓和支持不夠好,微信瀏覽器內(nèi)核不支持,雖然已經(jīng)升級到內(nèi)核,但是為了確保萬無一失,放棄采用這種方案。 如果在一個區(qū)域內(nèi)只允許部分區(qū)域產(chǎn)生滾動的效果,而其余部分不能移動,你會采用什么方法呢? 作者:Icarus原文鏈接:http://xdlrt.github.io/20...

    singerye 評論0 收藏0
  • 移動端實現(xiàn)內(nèi)滾動的4種方案

    摘要:部分區(qū)域固定其余區(qū)域滾動部分區(qū)域固定為頁面的部分設置以及,即禁用頁面原生的滾動,保證只會顯示一屏的內(nèi)容。但是單位對低版本安卓和支持不夠好,微信瀏覽器內(nèi)核不支持,雖然已經(jīng)升級到內(nèi)核,但是為了確保萬無一失,放棄采用這種方案。 如果在一個區(qū)域內(nèi)只允許部分區(qū)域產(chǎn)生滾動的效果,而其余部分不能移動,你會采用什么方法呢? 作者:Icarus原文鏈接:http://xdlrt.github.io/20...

    lscho 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<