溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何利用JS實(shí)現(xiàn)scroll自定義滾動(dòng)效果

發(fā)布時(shí)間:2021-04-21 13:40:43 來(lái)源:億速云 閱讀:357 作者:小新 欄目:web開發(fā)

小編給大家分享一下如何利用JS實(shí)現(xiàn)scroll自定義滾動(dòng)效果,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

js有什么特點(diǎn)

1、js屬于一種解釋性腳本語(yǔ)言;2、在絕大多數(shù)瀏覽器的支持下,js可以在多種平臺(tái)下運(yùn)行,擁有著跨平臺(tái)特性;3、js屬于一種弱類型腳本語(yǔ)言,對(duì)使用的數(shù)據(jù)類型未做出嚴(yán)格的要求,能夠進(jìn)行類型轉(zhuǎn)換,簡(jiǎn)單又容易上手;4、js語(yǔ)言安全性高,只能通過(guò)瀏覽器實(shí)現(xiàn)信息瀏覽或動(dòng)態(tài)交互,從而有效地防止數(shù)據(jù)的丟失;5、基于對(duì)象的腳本語(yǔ)言,js不僅可以創(chuàng)建對(duì)象,也能使用現(xiàn)有的對(duì)象。

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

因?yàn)槭亲远x手機(jī)端的滾動(dòng)事件,那我選擇的是監(jiān)聽手機(jī)端的三個(gè)touch事件來(lái)實(shí)現(xiàn)監(jiān)聽,并實(shí)現(xiàn)了兩種滾動(dòng)效果,一種是通過(guò)-webkit-transform,一種是通過(guò)top屬性。兩種實(shí)現(xiàn)對(duì)于滾動(dòng)的基本效果夠能達(dá)到,可是top的不適合滾動(dòng)中還存在滾動(dòng),可是能解決滾動(dòng)中存在postion:fixed屬性的問題;而transform可以實(shí)現(xiàn)滾動(dòng)中有滾動(dòng),可是又不能解決postion:fixed的問題,所以,最后選擇性考慮使用哪一種實(shí)現(xiàn)方式,用法一樣。

主要的實(shí)現(xiàn)業(yè)務(wù)邏輯

handleTouchMove(event){
 event.preventDefault();
 this.currentY = event.targetTouches[0].screenY;
 this.currentTime = new Date().getTime();
 // 二次及以上次數(shù)滾動(dòng)(間歇性滾動(dòng))時(shí)間和路程重置計(jì)算,0.05是間歇性滾動(dòng)的停頓位移和時(shí)間比
 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;
 /*設(shè)置移動(dòng)最小值*/
 temDis = temDis > this.minValue ? temDis * 1 / 3 : temDis;
 /*設(shè)置移動(dòng)最大值*/
 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),其中主要計(jì)算出目標(biāo)節(jié)點(diǎn)this.$el的top或者-webkit-transform中translateY的值,而計(jì)算的參考主要以事件節(jié)點(diǎn)的screenY的垂直移動(dòng)距離為參考,當(dāng)然其中還要判斷一下最大值和最小值,為了保證移動(dòng)可以的超出最大值小值一定的距離所以加了一個(gè)1/3的移動(dòng)計(jì)算。這里可能主要到了有一個(gè)間歇性滾動(dòng)的判斷和計(jì)算,主要是服務(wù)于慣性滾動(dòng)的,目的是讓慣性滾動(dòng)的值更加精確。

handleTouchEnd(event){
 /*點(diǎn)透事件允許通過(guò)*/
 if (!this.distance) return;
 event.preventDefault();
 let temDis = this.distance + this.oldY;
 /*計(jì)算緩動(dòng)值*/
 temDis = this.computeSlowMotion(temDis);
 /*設(shè)置最小值*/
 temDis = temDis > this.minValue ? this.minValue : temDis;
 /*設(shè)置最大值*/
 temDis = temDis < -this.maxValue ? -this.maxValue : temDis;
 this.$el.style["transitionDuration"] = '500ms';
 this.$el.style["transitionTimingFunction"] = 'ease-out';
 /*確定最終的滾動(dòng)位置*/
 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事件,并且這里還要計(jì)算慣性緩動(dòng)值,設(shè)置最終的最大最小值,以及設(shè)置動(dòng)畫效果和緩動(dòng)效果。下面來(lái)談一下滾性滾動(dòng)的計(jì)算:

// 計(jì)算慣性滾動(dòng)值
computeSlowMotion(temDis){
 var duration = new Date().getTime() - this.startTime;
 // 300毫秒是判斷間隔的最佳時(shí)間
 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;
 }
},

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

以上是“如何利用JS實(shí)現(xiàn)scroll自定義滾動(dòng)效果”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI