背景
最近開發公司的公眾號H5,做了一個點選icon滾動到頂部的功能。實現功能比較簡單,直接呼叫window.scrollTo(0, 0),一行程式碼完成。但是作為一個攻城獅,怎麼可能對自己要求這麼低,所以我給自己加了個需求,實現平滑滾動頁面到頂部的功能。經過調研和檢視文件,有了以下三種方案。
1.使用CSS
完成功能的最高境界,只用CSS就搞定。程式碼如下:
html {
scroll-behavior: smooth;
}
複製程式碼
該樣式的作用是為有滾動條的元素指定一個滾動的行為,但是隻有在當使用者手動導航或者 CSSOM scrolling API觸發滾動的時候生效,不影響使用者行為產生的滾動。就在我慶祝的時候,開啟can i use看了下相容性:
日了狗,還是老老實實用JS實現吧。2.使用Window.scrollTo API
我們都知道window.scrollTo(x, y),通過傳入文件中的x,y軸座標來實現滾動到頁面某個位置的功能。這個API其實還可以傳入一個option,是一個物件,left值對應座標中的x,top對應座標中的y,還有一個值為behavior,可以讓你自定義滾動行為,然後我們這樣來實現滾動到頂部:
window.scrollTo({
left: 0,
top: 0,
behavior: 'smooth'
})
複製程式碼
真香,搞定。過了幾天,產品經理扛著5米大刀來找我,說在Safari上滾動效果奇怪,體檢極差。於是我默默開啟了MDN文件,滾動到底部:
看到了這張圖,雖然API瀏覽器都幾乎支援,但是option選項在Safari上直接掛掉,於是我又開啟了stackoverflow,總結了終極方案。3.使用requestAnimationFrame
經常能看到大名鼎鼎的requestAnimationFrame,但是沒機會用上,這次可以嚐嚐鮮了。我們知道requestAnimationFrame的作用就是告訴瀏覽器在下次重繪之前執行傳入的回撥函式,這個行為是瀏覽器自動幫你做的。於是有了如下程式碼:
const scrollToTop = () => {
let sTop = document.documentElement.scrollTop || document.body.scrollTop
if (sTop > 0) {
window.requestAnimationFrame(scrollToTop)
window.scrollTo(0, sTop - sTop / 8)
}
}
複製程式碼
Done!!!Perfect!!!雀躍的同時,我還是開啟了can i use檢視了requestAnimationFrame的相容性:
晚上吃雞!!!