H5頁面滾動阻尼效果實現

功能描述

  • 要求javascript

    • 頁面分爲AB兩個區域css

    • 當手機可視區的底部接觸到 「阻尼帶」 的時候,有個上拉彈性過程java

      • 當上拉到必定閾值程度就直接把B區頂部彈到手機可視區的頂部,讓可視區從B區開始顯示
      • 當上拉程度未到閾值,就回彈復原
    • 當手機可視區從B區向上滾動時候,B區頂部接觸帶「阻尼帶」,有個下拉彈性過程webpack

      • 當下拉到必定閾值程度就直接把A區底部彈到手機可視區的底部,讓可視區從A區底部向上開始顯示
      • 當下拉程度未到閾值,就回彈復原
  • 提示git

    • 可用jQuery實現

具體實現過程

首先什麼是阻尼效果?上網查閱:github

阻尼(英語:damping)是指任何振動系統在振動中,因爲外界做用和/或系統自己固有的緣由引發的振動幅度逐漸降低的特性,以及此一特性的量化表徵。web

好吧,生澀難懂,沒能理解。不過網上有說此效果在iPhone上比較常見,直接上圖比較容易理解: 瀏覽器

阻尼效果

簡單來講,就是界面滑動到了最底部或最頂部仍能夠比實際的內容多滑動一段距離而後回彈的彈性效果。 從效果中能夠看出,有三個重點:性能

  • 滑動到最頂部或最底部纔出現。
  • 表現出比實際的內容多滑動一段距離,實際操做知道,多滑動的距離便是手指在屏幕上滑動的距離。
  • 放開手以後,有回彈效果。

已經知道什麼是阻尼效果了,如今思考如何去實現。 對於第二點,咱們能夠監聽 touchstart, touchmove, touchend 事件,跟鼠標拖拽的原理相似:動畫

  1. touchstart 時,記下起點位置;
  2. touchmove 實時計算滑動的距離。
  3. touchend 時,能獲得最終的滑動距離,跟設定的閾值比較。進入到頁面自動控制階段:大於閾值則讓頁面滑動到下一頁,小於閾值則恢復到起始位置。

在我實現的過程當中,想過兩種方案。

  1. 利用Js 大體思路是,經過監測滾輪事件,檢測到頁面已經滑動到最底部(最頂部同理),計算手指在頁面的滑動距離,touchmove事件觸發時,給下面的阻尼帶增長padding-bottom,形成頁面跟着手指多滑動一段距離的假象。 缺點:利用js實現動畫比較耗費性能。

  2. 利用css 第二個方案採用css動畫,頁面多滑動一段距離,實際上也能夠經過把頁面往手指滑動的方向translate一段距離,這個時候頁面只要背景色相同,也能夠實現相同效果。 由於translate能夠出發瀏覽器硬件加速,能夠保證性能。

能用 css 作的,絕對不要用 js 解決。

可是在第二種方案實現過程當中發現一個問題,若是咱們在滑動一段距離後纔到達最底部,這時候不鬆開手,又往回滑,就會出現bug。

bug

我是經過監測滾動條的位置判斷是否到達底部。

$(document).scroll(() => {
    isBottom = document.scrollTop() >= $(document).height() - $(window).height();
});
複製代碼

由於往回滑的過程,滾動條也往上滑動,致使isBottom錯誤,出現bug。

上網查閱了不少資料,沒有找到理想的解決辦法,可是找到一個移動端插件:Swiper,這是純javascript打造的滑動特效插件,面向手機、平板電腦等移動終端。這個插件也實現了阻尼效果。 經過看它的源碼發現,Swiper也是利用translate的方法,將頁面往上移動一段距離,可是滾動條是本身實現的,也就是經過設置外面容器的overflow: hidden來禁用原生滾動條,本身從新實現一個。 道理很簡單,咱們能夠經過touch事件translate頁面,一樣也能夠translate滾動條,這樣達到本身可控。

找到解決辦法,仿照Swiper的思路(可是省去了滾動條部分的代碼實現,就是頁面沒有滾動條),粗略實現了阻尼效果。

最終效果

詳細代碼見個人github。其中利用了webpack進行打包編譯。

相關文章
相關標籤/搜索