今天我們一起來用 JavaScript 實(shí)現(xiàn)一個(gè)回到頂部的功能。
首先,需要梳理一下我們需求:
- 在頁面的右下角有一個(gè)"回到頂部"的按鈕
- 點(diǎn)擊這個(gè)按鈕不是直接回到頂部而是要以漸慢的速度回到頂部
- 在回到頂部的滾動(dòng)中如果用戶滑動(dòng)鼠標(biāo)的滾動(dòng)輪則停止回到頂部的滾動(dòng)效果
- 只有在滾動(dòng)超過頁面可視窗口高度之后才顯示"回到頂部"的按鈕,否則隱藏"回到頂部"按鈕
首先先寫出最基本的 HTML 結(jié)構(gòu):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js 回到頂部</title>
<style media="screen">
body,html {
margin: 0;
padding: 0;
}
#box {
width: 1190px;
margin: 0 auto;
}
#box > div {
background-color: #eee;
height: 10000px;
}
#btn {
height: 30px;
width: 100px;
background-color: #eee;
position: fixed;
right: 0px;
bottom: 40px;
-webkit-transition: background-color 1s;
-o-transition: background-color 1s;
transition: background-color 1s;
}
#btn:hover {
background-color: #ff0;
cursor: pointer;
}
</style>
</head>
<body>
<div id="box">
<div>用來撐開空間高度</div>
</div>
<div id="btn">回到頂部</div>
</body>
<script type="text/javascript">
/* 這里添加 js 代碼 */
</script>
</html>
本文主要實(shí)現(xiàn)功能,css 這塊不太好看希望諒解 _
接下來要實(shí)現(xiàn)點(diǎn)擊"回到頂部"的執(zhí)行事件
第一步呢,先實(shí)現(xiàn)點(diǎn)擊按鈕直接向上滾動(dòng) 200 像素的效果
window.onload = function() {
var obtn = document.getElementById('btn');
obtn.onclick = function() {
// 獲取當(dāng)前視圖最上方距這個(gè)內(nèi)容區(qū)最頂部的距離(也就是已經(jīng)滾動(dòng)的距離)
var osTop = document.documentElement.scrollTop || document.body.scrollTop;
// 其實(shí)這里寫法并不好
document.body.scrollTop = document.documentElement.scrollTop -= 200;
}
}
第二步,給上面這個(gè)向上滾動(dòng) 200 像素的動(dòng)作添加一個(gè)定時(shí)器自動(dòng)執(zhí)行,就實(shí)現(xiàn)了一個(gè)緩慢向上滾動(dòng)到頂部的效果,注意當(dāng)滾動(dòng)到頂部的時(shí)候需要清除計(jì)時(shí)器。
第三步,改變這個(gè) 200 像素的值,速度的值應(yīng)該是越靠頂部越慢的,所以還需要計(jì)算這個(gè)值。
下面是這部分的代碼
var obtn = document.getElementById('btn');
// 定時(shí)器
var timer = null;
obtn.onclick = function() {
// 速度值
var speed = 0;
// 當(dāng)前視圖最上方距這個(gè)內(nèi)容區(qū)最頂部的距離(也就是已經(jīng)滾動(dòng)的距離)
var osTop = 0;
timer = setInterval(function() {
osTop = document.documentElement.scrollTop || document.body.scrollTop;
// 改變回到頂部的速度(越來越慢)
// 注意此處是向上取整
speed = Math.ceil(-osTop / 2);
document.body.scrollTop = document.documentElement.scrollTop -= (osTop + speed);
if (speed === 0) {
clearInterval(timer);
}
}, 30);
}
完成到此其實(shí)基本的回到頂部的功能就已經(jīng)完成了,下面就是一些優(yōu)化操作。
第四步,如果在滾動(dòng)回到頂部的過程中,用戶滑動(dòng)了鼠標(biāo)的滾輪,那就停止回到頂部的滾動(dòng)操作。此處我們需要調(diào)用 onmousewheel ,暫不考慮此方法的瀏覽器兼容性問題,代碼如下:
// 監(jiān)聽鼠標(biāo)滑輪的滾動(dòng)事件
window.onmousewheel = function() {
clearInterval(timer);
}
最后一步,就是只有在滾動(dòng)超過頁面可視高度后才顯示"回到頂部"按鈕,否則隱藏該按鈕,以下是代碼:
#btn {
/* other code... */
display: none;
}
// 獲取頁面的可視窗口高度
var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
var obtn = document.getElementById('btn');
// 頁面滾動(dòng)時(shí)增加判斷,超出頁面可視化高度時(shí)顯示回到頂部的按鈕
window.onscroll = function() {
// 此處需要重新聲明,因?yàn)楹蜕厦娴?osTop 不在同一個(gè)函數(shù)域,不可忽略!
var osTop = document.documentElement.scrollTop || document.body.scrollTop;
if (osTop > clientHeight) {
obtn.style.display = 'block';
} else {
obtn.style.display = 'none';
}
}
寫到此處一個(gè)回到頂部的功能就完成啦,是不是非常簡(jiǎn)單呢~
下面是完整的頁面代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js回到頂部</title>
<style media="screen">
body, html {
margin: 0;
padding: 0;
}
#box {
width: 1190px;
margin: 0 auto;
}
#box > div {
background-color: #eee;
height: 10000px;
}
#btn {
height: 30px;
line-height: 30px;
width: 100px;
background-color: #eee;
position: fixed;
right: 0px;
bottom: 40px;
display: none;
-webkit-transition: background-color 1s;
-o-transition: background-color 1s;
transition: background-color 1s;
}
#btn:hover {
background-color: #ff0;
cursor: pointer;
}
</style>
</head>
<body>
<div id="box">
<div>占位</div>
</div>
<div id="btn">回到頂部</div>
</body>
<script type="text/javascript">
window.onload = function() {
var obtn = document.getElementById('btn');
// 定時(shí)器
var timer = null;
// 獲取頁面的可視窗口高度
var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
obtn.onclick = function() {
var osTop = 0;
var speed = 0;
timer = setInterval(function() {
isScroll = true;
// 距內(nèi)容區(qū)最頂部的距離
osTop = document.documentElement.scrollTop || document.body.scrollTop;
// 改變回到頂部的速度(越來越慢)
speed = Math.ceil(-osTop / 1.05);
document.body.scrollTop = document.documentElement.scrollTop -= (osTop + speed);
if (speed == 0) {
clearInterval(timer);
isScroll = false;
}
}, 30);
};
// 監(jiān)聽鼠標(biāo)滑輪的滾動(dòng)事件
window.onmousewheel = function() {
clearInterval(timer);
};
// 頁面滾動(dòng)時(shí)增加判斷,超出頁面可視化高度時(shí)顯示回到頂部的按鈕
window.onscroll = function() {
var osTop = document.documentElement.scrollTop || document.body.scrollTop;
if (osTop > clientHeight) {
obtn.style.display = 'block';
} else {
obtn.style.display = 'none';
}
};
};
</script>
</html>
其實(shí)這是一個(gè)非常簡(jiǎn)單的功能,也是提醒大家在使用框架的同時(shí),這些 JavaScript 底層的功能也不要忘記,因?yàn)榧夹g(shù)在不斷的更新但是底層的知識(shí)是不會(huì)變的。