由于最近要實(shí)現(xiàn)這個(gè)功能,沒有發(fā)現(xiàn)比較完善比較滿意的實(shí)現(xiàn)思路饮戳。所以豪治,自己寫了一版。請(qǐng)教了大神一種比較好的思路莹捡,寫出來(lái)分享一下~
實(shí)現(xiàn)頁(yè)面滾動(dòng)到目標(biāo)位置鬼吵,可以向上或向下扣甲。
這個(gè)功能用jQuery實(shí)現(xiàn)比較容易篮赢,三五行搞定齿椅,但是,有時(shí)候启泣,總不能為了實(shí)現(xiàn)一個(gè)滾動(dòng)效果去多引入一個(gè)庫(kù)涣脚,所以,現(xiàn)在我們拋開jQuery庫(kù)寥茫,用原生JS實(shí)現(xiàn)遣蚀。
實(shí)現(xiàn)動(dòng)畫的API:requestAnimationFrame
頁(yè)面滾動(dòng)的API:window.scrollTo()
思路步驟:
獲取元素。
獲取元素到屏幕頂部的距離 top
: getBoundingClientRect
纱耻。
獲取頁(yè)面已滾動(dòng)的距離 pageY
: pageYOffset
芭梯。
得到目標(biāo)位置 endPosition
: top+pageY
。
requestAnimationFrame 是在顯示器屏幕刷新一幀時(shí)候執(zhí)行一次傳入的run
函數(shù)弄喘。
設(shè)定動(dòng)畫持續(xù)時(shí)間 duration=500ms玖喘,
定義run
函數(shù),顯示器每刷新一幀蘑志,則循環(huán)調(diào)用一次run
函數(shù)累奈。
每次調(diào)用run
的時(shí)候,獲取時(shí)間差急但,根據(jù)時(shí)間-位置對(duì)應(yīng)的值澎媒,根據(jù)時(shí)間得到此刻應(yīng)該滾動(dòng)到的位置,window.scrollTo
到這個(gè)位置波桩。
根據(jù)時(shí)間設(shè)定要滾動(dòng)到的位置戒努。如果到了規(guī)定時(shí)間,頁(yè)面應(yīng)該在目標(biāo)位置镐躲。否則直接滾動(dòng)到目標(biāo)位置柏卤。
scroll = (ev, target) => {
ev.preventDefault();
const scrollPart = document.querySelector('.' + target); // 目標(biāo)節(jié)點(diǎn)class
const top = scrollPart.getBoundingClientRect().top;
const pageY = window.pageYOffset;
const endPosition = top + pageY;
const startTime = +new Date();
const duration = 500; //ms
function run() {
const time = +new Date() - startTime;
window.scrollTo(0, pageY + top * (time / duration));
run.timer = requestAnimationFrame(run);
if (time >= duration) {
window.scrollTo(0, endPosition);
cancelAnimationFrame(run.timer);
}
}
requestAnimationFrame(run);
}
scroll();