返回頂部的幾種實現
返回頂部的按鈕大家并不陌生,針對長滾動條的信息流頁面添加返回頂部的按鈕可以給用戶良好的體驗,而返回頂部的實現也是多種多樣,本文分享幾個案例并給出評價
作為引子講一個常用的案例,對與不知道的作為一個小彩蛋吧!對于微博與微信朋友圈的返回頂部可以雙擊最頂部的區域(包含時間,網絡,電量)來返回頂部
大家見過哪些創意的返回頂部呢?歡迎留言交流,下面進入正文
直接跳轉的方式
對于追求極簡的方式達到預期效果的人可能會喜歡這種方式,不托泥帶水也不用考慮兼容問題
國內的大站如 新浪主頁 , 淘寶網 , 京東 , 百度新聞
不難發現此類的大站為了兼容性與瀏覽器渲染速度選擇了 直接跳轉的方式 ,實現基本含兩種方式
命名錨點跳轉的方式
用錨點 #top(可變)返回到頂部預設的 id 為 top(可變)的元素,或者在頁面頂部的 a 標簽 name 屬性值為 top(可變),新版本的瀏覽器(chrome等)默認支持 #top 錨點返回頂部且不需要前面所提條件,但是前面條件的優先級大于默認跳轉。
上面說的有些繞口,下面逐句解釋,讀明白且理解的可以直接看下節
<a href="#top">返回頂部</a> <!-- fiexd 定位在頁面右下角 -->
<p id="top">頂部</p> <!-- id 為 top -->
<a name="top"></a> <!-- a 標簽且 name 為 top -->
上面代碼包含了所有的描述,簡單易懂,下面說下優先級,這個是關鍵,避免無意中犯了錯誤卻無從下手
注意: id > name > 默認
不建議大家用默認的方式,具體有兼容問題和優先級低的問題,id 與 name 均可,但要注意命名沖突
scroll 函數跳轉
window.scroll(x, y) 方法,x 是水平滾動位置,y 是垂直滾動位置,必須兩個參數都給進去不然會報錯,大家可能發現有 window.scrollY,這里只改變垂直方向的滾動為什么不能用,一個方面它返回的不是函數無法傳參,另一方面無法被賦值
<a href="javascript: scroll(0, 0)">返回頂部</a>
這里方便展示,實際不建議在標簽內使用 js,可以調用一個方法,簡單易懂。
setTimeout 模擬滾動動畫
setTimeout() 方法遞歸調用,改變滾動條距頂部位置
function backTop () {
window.scrollBy(0, -100)
scrolldelay = setTimeout('backTop()', 10)
var sTop = document.documentElement.scrollTop + document.body.scrollTop
if (sTop === 0) {
clearTimeout(scrolldelay)
}
}
注意優化網頁資源,使用不當會非常卡頓,可以通過調節 setTimeout 的第二個參數來控制滾動速度(回調時間單位 ms),下面解釋聲明sTop 變量的寫法
獲取scrollTop值,聲明了DTD的標準網頁取 document.documentElement.scrollTop,否則取 document.body.scrollTop 因為二者只有一個會生效,另一個就恒為 0,所以取和值可以得到網頁的真正的 scrollTop 值
注:非標準版(webkit 內核)采用的是 document.body.scrollTop
window.requestAnimationFrame
window.requestAnimationFrame() 這個方法是用來在頁面重繪之前,通知瀏覽器調用一個指定的函數,以滿足開發者操作動畫的需求。這個方法接受一個函數為參,該函數會在重繪前調用。
完整的文檔看 MDN 和 JavaScript 標準參考教程(alpha) ,里面有詳細描述和兼容性詳情
看過文檔發現 requestAnimationFrame 適合用于連續的動畫,而我們的需求與連續動畫關系大嗎?我們不妨一試。
const isWebkit = navigator.userAgent.toLowerCase().match(/webkit\/([\d.]+)/)
const requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame
function backTop () {
let move = window.scrollY
let span = move / 15
function step () {
if (document.documentElement.scrollTop + document.body.scrollTop > 0) {
if (isWebkit) {
document.body.scrollTop -= 300
} else {
document.documentElement.scrollTop -= 300
}
requestAnimationFrame(step)
} else {
return
}
}
requestAnimationFrame(step)
}
上面代碼為什么定義 move 與 span 這里是方便計算速度,粘貼代碼運行你會發現滾動的距離越大速度就會越快,反而會越慢
這種用法本質上可以使動畫更加流暢,但是重點在于頁面優化,requestAnimationFrame是在主線程上完成。這意味著,如果主線程非常繁忙,requestAnimationFrame的動畫效果會大打折扣。
借助 jQuery
目前的前端把焦點從 jQuery 移到了 MVVM 框架,不論如何當初的 jQuery 對于 DOM 操作與低版本瀏覽器兼容貢獻巨大。如果你即考慮兼容性又想要流暢的動畫可以繼續使用 jQuery。
function backTop (minHeight) {
var backTopHtml = '<div id="backTopBtn">返回頂部</div>'
$('#page').append(backTopHtml)
$('#backTopBtn').click(function () {
$('html, body').animate({scrollTop: 0}, 700)
}).hover(
function () {
$(this).addClass('hover')
},
function () {
$(this).removeClass('hover')
}
)
minHeight ? minHeight = minHeight : minHeight = 600
$(window).scroll(function () {
var s = $(window).scrollTop()
if (s > minHeight) {
$('#backTopBtn').fadeIn(100)
} else {
$('#backTopBtn').fadeOut(100)
}
})
}
backTop()
這里初始狀態的返回頂部為不可見,通過判斷頁面滾動高度切換顯示隱藏,hover 的樣式可以自己設計。
總結
總結了幾種返回頂部的方式,orange 認為滾動或跳轉對用戶體驗并沒有影響(影響用戶體驗的是有沒有返回頂部的按鈕),既然選擇了返回頂部的按鈕那么性能一定是第一位的,一味追求滾動動畫導致頁面滾動過程中卡頓進而影響了整個網頁的用戶體驗,在這個細節上負面的例子太多不一一列舉。
總之本文的用意除了闡述各個方法的用法外還想提醒大家在前端開發中細節才是致命的,orange 也一直在踩坑,說到聰明的大廠為什么選用跳轉,哈哈,先回去看看負面教材給我們的教訓就知道了,技術點不在于滾動,而在于整個網頁的優化,如果你的網站優化的足夠好,那么拿滾動來炫技沒人會反對。
來自:http://orangexc.xyz/2016/12/07/Back-to-top/