前段時間拜讀阮老師的 《ECMAScript 6 入門》 ,看到官網上每個章節的頁面都有一個類似進度條的東西,出於好奇,上網查了一下,發現這個東西叫Scroll Indicator
.
Scroll Indicator:滾動指示器。通俗來說,就是當前可視區域距離頁面頂部的佔比,效果如下:
JavaScript的做法
在還沒有撈原始碼之前,自己先大致想了一下實現思路:
- 頁面載入完成之後,獲取到頁面文件高度(DH)、當前可視區域高度(VH)、可視區域距離頁面頂部的高度
scrollTop
(TH); - (DH - VH)就是需要滾動的值;
- 監聽頁面
scroll
事件,(TH / (DH - VH)) * 100%
,便是當前的佔比; - 當然,需要考慮
節流
、防抖
。
核心程式碼如下:
var dh = $(document).height();
var vh = $(window).height();
var sHeight = dh - vh;
$(window).scroll(function() {
var perc = $(window).scrollTop() / (dh - vh);
$('.j-scroll-indicator').css({width: perc * 100 + '%'});
)};複製程式碼
這是實現之後的效果:
然後去撈了一下阮老師es6官網的原始碼:
(function() {
var $w = $(window);
var $prog2 = $('.progress-indicator-2');
var wh = $w.height();
var h = $('body').height();
var sHeight = h - wh;
$w.on('scroll', function() {
window.requestAnimationFrame(function(){
var perc = Math.max(0, Math.min(1, $w.scrollTop() / sHeight));
updateProgress(perc);
});
});
function updateProgress(perc) {
$prog2.css({width: perc * 100 + '%'});
ditto.save_progress && store.set('page-progress', perc);
}
}());複製程式碼
不出所料,做法是一樣的。
然後,就開始瞎琢磨,之前用 css
搞過瀑布流,那可以用 css
搞滾動指示器嗎?
CSS的做法
使用 CSS
來實現滾動指示器,難點在於:如何實時去獲取當前可視區域在文件流中的位置。
上述問題,如何去考慮呢?我們從分解滾動指示器的動作中來找答案:
- 黑色表色進度條
- 紅色表示文件高度
- 綠、藍、橙表示視窗滾動
也就是說:(TH / (DH - VH))
公式中的 TH
可以不用知道,只需要DH - VH
的高度,即直角三角形的高度便OK。
現在問題轉化為:如何求出VH,這時候該 vh
這個長度單位登場了,vh 是基於視窗單位的排版計量。vh可以獲取當前視窗的高度。嗯,現在看來,應該是可以一寫了。
<body>
<div class="main">
<h1>滾動滑鼠</h1>
</div>
</body>複製程式碼
.main {
margin: 0;
padding: 0;
display: block;
height: 30000px;
text-align: center;
line-height: 100px;
}
body {
margin: 0;
padding: 0;
background: linear-gradient(to right top, #369 50%, #fff 50%);
background-size: 100% calc(100% - 99vh);
}
body:before {
content: '';
position: fixed;
top: 4px;
bottom: 0;
width: 100%;
z-index: -1;
background: #fff;
}複製程式碼
大致實現是沒有問題的,但是有下面幾個缺點:
- 文件內容太少(高度太小)的話,進度條呈箭頭形,不美觀(可考慮加毛玻璃效果來弱化)
background-size: 100% calc(100% - 99vh);
中的99vh是相對值,若是視窗高度比較小,進度條會填不滿進度條槽(可考慮加min-height來弱化)
以上