首頁  >  文章  >  web前端  >  JS实现scroll自定义滚动效果

JS实现scroll自定义滚动效果

小云云
小云云原創
2018-01-15 13:16:022091瀏覽

本文主要為大家介紹了關於利用JS如何實現scroll自訂滾動效果的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。希望能幫助大家。

前言

最近在公司開發專案的時候,原生捲軸中有些東西沒辦法自訂去精細的控制,於是開發一個類似better-scroll一樣的瀏覽器滾動監聽的JS實現,下面我們就來探究一下自訂滾動需要考慮哪些東西,經過哪些過程。話不多說了,來一起看看詳細的介紹吧。

選擇滾動監聽的事件

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

主要的實作業務邏輯

handleTouchMove(event){
 event.preventDefault();
 this.currentY = event.targetTouches[0].screenY;
 this.currentTime = new Date().getTime();
 // 二次及以上次数滚动(间歇性滚动)时间和路程重置计算,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 + &#39;px&#39;;
 this.lastY = this.currentY;
 this.lastTime = this.currentTime;
 this.dispatchEvent();
 this.scrollFunc(event);
},

程式碼解讀:這是監聽touchmove事件的回調,其中主要計算出目標節點this.$el的top或-webkit-transform中translateY的值,而計算的參考主要以事件節點的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"] = &#39;500ms&#39;;
 this.$el.style["transitionTimingFunction"] = &#39;ease-out&#39;;
 /*确定最终的滚动位置*/
 setTimeout(()=> {
  this.$el.style["top"] = temDis + 'px';
 }, 0);
 // 判断使用哪一种监听事件
 if (this.slowMotionFlag) {
  this.dispatchEventLoop();
 } else {
  this.dispatchEvent();
 }
 this.$el.addEventListener('transitionend', ()=> {
  window.cancelAnimationFrame(this.timer);
 });
 this.scrollFunc(event);
}

程式碼解讀:這是touchend事件監聽的回調,其中這裡要判斷是否要攔截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;
 }
},

程式碼解讀:滾性滾動的演算法主要是根據一個路程和時間計算出初速度,以及原生滾動的加速度的大於值0.006來計算滾動的總位移。這裡主要還要判斷一個300ms的經驗值。

總結

大概的流程和思考就是這樣了,後續還會增加更多的功能進行擴充

附上git位址:https://github.com /yejiaming/scroll

相關推薦:

關於jQuery滾動外掛scrollable.js用法分析

##微信小程式scroll -view元件詳解

vue利用better-scroll實作輪播圖與頁面捲動

以上是JS实现scroll自定义滚动效果的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn