相信很多人都在項目中用過這么一個玩意 —— .js庫,或者是其它類似的庫,它們的作用很實用:頁面加載進度提示。顧名思義,就是在剛進入頁面或刷新或請求數據時在頁面頂部有一個進度條給用戶以反饋,使頁面加載顯得不那么“尷尬”。
但只有很少人見過 “在頁面頂部實時反饋當前閱讀進度” 的效果 —— 為什么?因為有滾動條。但不得不提的是:這真的很有用!不管是“在有些要求高的頁面對自帶滾動條很厭惡”還是“即使有滾動條也可以給用戶更好看的提示效果”。當然,目前第一種場景比較多。
用JS達到實時進度提示效果
這得益于JS的一些“別致”的API ——
★
這里需要注意的是:指的是啥?頁面滾動條縱坐標位置。也就是頁面相對于窗口顯示區左上角的Y坐標。所以有的地方也用下面的API代替:.
”
回到我們這個想法中:其實我們要展示出來的,不就是“當前向上滑動了多少”與“文檔區域總高度”的比例嗎?那如果實時監聽變化并展示到頁面上頁面加載時顯示進度條,不就成了?
let?scrollHeight=document.documentElement.scrollHeight;
let?clientHeight=document.documentElement.clientHeight;
document.addEventListener('scroll',function(e){
?let?scrollTop=document.documentElement.scrollTop?||?document.body.scrollTop;
?const?sizeHeight=+(scrollTop/(scrollHeight-clientHeight)).toFixed(2)*100;
?console.log(sizeHeight)
})
然后將其展示到頁面上 —— 采用css控制父元素位置、js控制子元素width的方式渲染:
<div?class="pro_bar">
????<div?class="bar_cess">div>
div>
.pro_bar{
????position:?fixed;
????top:?0;
????left:?0;
????width:?100%;
????height:?3px;
????background-color:?#DDD;
????overflow:?hidden;
}
.pro_bar?.bar_cess{
????position:?absolute;
????left:?0;
????height:?100%;
????background-color:?#0089f2;
}
let?scrollHeight=document.documentElement.scrollHeight;
let?clientHeight=document.documentElement.clientHeight;
let?bar=document.querySelector('.bar_cess');
document.addEventListener('scroll',function(e){
????let?scrollTop=document.documentElement.scrollTop?||?document.body.scrollTop;
????const?sizeHeight=+(scrollTop/(scrollHeight-clientHeight)).toFixed(2)*100;
????bar.style.width=sizeHeight+"%";
})
但js實現難免會遇到比如“回流和重繪”一類的性能問題。通常一看到監聽之流就會下意識的“防抖”、“節流”、“脫離文檔流渲染”…如臨大敵。其實dark不必:
用CSS實現進度提示
這個的實現原理也很簡單,是筆者之前提過的 —— - ,嘿嘿,沒想到吧?讓我來帶各位逐步分析:
首先,是-的第一個參數。它是規定方向的 —— 這里需要注意的是:它實際相當于“劃”了一條線,按你規定的方向從你規定的比例中將頁面給分割開(這一點具體的參見我這篇文章),比如 -(to right top, # 50%, #DDD 50%) ,效果如下:
有了這么一個“藍色三角形”,你有沒有想到什么?
如果控制寬高把這部分大小設置為“滾動條拉到最底部時藍色區域的最底部也剛好到頁面頂部”,就像這樣:
那豈不就接近我們想要的效果了?這有兩種實現方式!
第一種方式:
body{
????background:?linear-gradient(to?right?top,?#0089f2?50%,?#DDD?50%);
????background-size:?100%?calc(100%?-?122vh?+?129px);
????background-repeat:?no-repeat;
}
通過 -size 設置了漸變的大小:
進一步說,我們需要的是一個頂部的滾動條,而不是全屏的三角塊 —— 大方向已經確定了,這時候就可以通過偽元素去覆蓋三角形背景區域,使之只在頂部一小塊區域內展示出來!
★
為什么要用偽元素呢?其實更確切地說還是 ::/::after,因為偽元素不在文檔流之內,方便渲染和控制,而且,這里設置-的是,我們如果想要實現“覆蓋”,也就只能用一個“屬于相同元素自身”的屬性去實現。綜合來說,在類似場景下,偽元素是最好的選擇了。
”
實現代碼:
<main>
????<h2>I?was?interested?to?see?if?I?could?make?a?scroll?indicator??with?just?CSS.h2>
????<p>You?can!?But?maybe?you?shouldn't.?This?is?an?interesting?consequence?of?a?bunch?of?hacks?held?together?with?duct?tape.?It?uses?z-index?hacks,?gradient?hacks?and?tricks?with?calc?and?viewport?units.p>
????<p>Having?said?that,?hacks?are?not?always?bad.?I?love?hacks?and?many?of?us?have?made?quite?a?good?living?selling?floats?and?clearfixes.p>
????<p>The?techniques?used?here?are?well?supported,?if?not?conventional.?If?you?can?read?the?CSS,?understand?how?it?works,?and?how?to?change?it,?and?you?think?this?works?better?for?you?than?JavaScript,?feel?free?to?implement?it.?Just?be?aware?of?the?z-index?behaviour?and?possible?conflict?with?other?CSS?using?negative?z-index.p>
????<hr>
????<h3>Tristique?Aenean?Etiam?Crash3>
????<p>Donec?id?elit?non?mi?porta?gravida?at?eget?metus.?Donec?ullamcorper?nulla?non?metus?auctor?fringilla.?Nulla?vitae?elit?libero,?a?pharetra?augue.?Donec?sed?odio?dui.?Donec?id?elit?non?mi?porta?gravida?at?eget?metus.?Praesent?commodo?cursus?magna,?vel?scelerisque?nisl?consectetur?et.p>
????<p>Cras?mattis?consectetur?purus?sit?amet?fermentum.?Donec?id?elit?non?mi?porta?gravida?at?eget?metus.?Integer?posuere?erat?a?ante?venenatis?dapibus?posuere?velit?aliquet.?Etiam?porta?sem?malesuada?magna?mollis?euismod.?Cum?sociis?natoque?penatibus?et?magnis?dis?parturient?montes,?nascetur?ridiculus?mus.?Donec?ullamcorper?nulla?non?metus?auctor?fringilla.p>
????<p>Aenean?eu?leo?quam.?Pellentesque?ornare?sem?lacinia?quam?venenatis?vestibulum.?Fusce?dapibus,?tellus?ac?cursus?commodo,?tortor?mauris?condimentum?nibh,?ut?fermentum?massa?justo?sit?amet?risus.?Donec?ullamcorper?nulla?non?metus?auctor?fringilla.?Sed?posuere?consectetur?est?at?lobortis.?Cras?justo?odio,?dapibus?ac?facilisis?in,?egestas?eget?quam.?Aenean?lacinia?bibendum?nulla?sed?consectetur.?Nulla?vitae?elit?libero,?a?pharetra?augue.p>
????<p>Donec?sed?odio?dui.?Vivamus?sagittis?lacus?vel?augue?laoreet?rutrum?faucibus?dolor?auctor.?Cras?mattis?consectetur?purus?sit?amet?fermentum.?Maecenas?sed?diam?eget?risus?varius?blandit?sit?amet?non?magna.p>
????<ul>
????????<li>Ullamcorper?Aenean?Ornareli>
????????<li>Ridiculus?Lorem?Malesuada?Consecteturli>
????????<li>Aenean?Tristique?Sit?Lorem?Purusli>
????????<li>Vehicula?Egestas?Mollis?Cursus?Nibhli>
????ul>
????<p>Vivamus?sagittis?lacus?vel?augue?laoreet?rutrum?faucibus?dolor?auctor.?Sed?posuere?consectetur?est?at?lobortis.?Sed?posuere?consectetur?est?at?lobortis.?Maecenas?faucibus?mollis?interdum.?Nullam?id?dolor?id?nibh?ultricies?vehicula?ut?id?elit.?Aenean?lacinia?bibendum?nulla?sed?consectetur.?Nullam?quis?risus?eget?urna?mollis?ornare?vel?eu?leo.p>
????<h3>Bibendum?Aenean?Dapibus?Tristiqueh3>
????<p>Cras?mattis?consectetur?purus?sit?amet?fermentum.?Donec?id?elit?non?mi?porta?gravida?at?eget?metus.?Integer?posuere?erat?a?ante?venenatis?dapibus?posuere?velit?aliquet.?Etiam?porta?sem?malesuada?magna?mollis?euismod.?Cum?sociis?natoque?penatibus?et?magnis?dis?parturient?montes,?nascetur?ridiculus?mus.?Donec?ullamcorper?nulla?non?metus?auctor?fringilla.p>
????<p>Aenean?eu?leo?quam.?Pellentesque?ornare?sem?lacinia?quam?venenatis?vestibulum.?Fusce?dapibus,?tellus?ac?cursus?commodo,?tortor?mauris?condimentum?nibh,?ut?fermentum?massa?justo?sit?amet?risus.?Donec?ullamcorper?nulla?non?metus?auctor?fringilla.?Sed?posuere?consectetur?est?at?lobortis.?Cras?justo?odio,?dapibus?ac?facilisis?in,?egestas?eget?quam.?Aenean?lacinia?bibendum?nulla?sed?consectetur.?Nulla?vitae?elit?libero,?a?pharetra?augue.p>
????<p>Donec?sed?odio?dui.?Vivamus?sagittis?lacus?vel?augue?laoreet?rutrum?faucibus?dolor?auctor.?Cras?mattis?consectetur?purus?sit?amet?fermentum.?Maecenas?sed?diam?eget?risus?varius?blandit?sit?amet?non?magna.p>
????<ul>
????????<li>Ullamcorper?Aenean?Ornareli>
????????<li>Ridiculus?Lorem?Malesuada?Consecteturli>
????????<li>Aenean?Tristique?Sit?Lorem?Purusli>
????????<li>Vehicula?Egestas?Mollis?Cursus?Nibhli>
????ul>
????<p>Vivamus?sagittis?lacus?vel?augue?laoreet?rutrum?faucibus?dolor?auctor.?Sed?posuere?consectetur?est?at?lobortis.?Sed?posuere?consectetur?est?at?lobortis.?Maecenas?faucibus?mollis?interdum.?Nullam?id?dolor?id?nibh?ultricies?vehicula?ut?id?elit.?Aenean?lacinia?bibendum?nulla?sed?consectetur.?Nullam?quis?risus?eget?urna?mollis?ornare?vel?eu?leo.p>
????<h2>Vivamus?sagittis?lacus?vel?augue?laoreet?rutrum?faucibus?dolor?auctor.h2>
????<p>Cras?mattis?consectetur?purus?sit?amet?fermentum.?Donec?id?elit?non?mi?porta?gravida?at?eget?metus.?Donec?id?elit?non?mi?porta?gravida?at?eget?metus.?Aenean?lacinia?bibendum?nulla?sed?consectetur.p>
main>
html,body?{?margin:0;padding:?0;}
@supports?(height:?100vh)?{
????body{
????????background:?linear-gradient(to?right?top,?#0089f2?50%,?#DDD?50%);
????????background-size:?100%?calc(100%?-?122vh?+?129px);?/**?這里“%”換成“vw”也可?*/
????????background-repeat:?no-repeat;
????}
????body::before{
????????content:'';
????????position:?fixed;
????????top:?2px;
????????bottom:?0;
????????width:?100%;
????????z-index:?-1;
????????background:?#fff;?/**?這個才是真正頁面的背景!不管是顏色還是圖片都在這里替換!?*/
????}
}
這種方法當然也有一絲缺點:它需要“只能偏大不能偏小”的控制-size的寬度頁面加載時顯示進度條,但是這顯然不適應精確在不同分辨率大小且需要響應式的屏幕中展示!
第二種方法:經過上面的折騰,我想我們已經掌握了“密碼”:定位+覆蓋。如果你不想直接在body中操作,你完全可以再定義一個元素,讓它跟隨body定位不就可以了?因為body是不會動的,相對body定位就可以達到fixed效果!
--?在body下添加一個空標簽?-->
<div?class="scroll_fixed">div>
body?{
????position:?relative;
}
.scroll_fixed?{
????position:?absolute;
????top:?0;
????right:?0;
????left:?0;
????bottom:?0;
????background:?linear-gradient(to?right?top,?#0089f2?50%,?transparent?50%)?no-repeat;
????background-size:?calc(100%?+?5px)?calc(100%?-?100vh?+?17px);
????z-index:?1;
????pointer-events:?none;
????mix-blend-mode:?darken;
}
.scroll_fixed::after?{
????content:?'';
????position:?fixed;
????top:?2px;
????bottom:?0;
????right:?0;
????left:?0;
????background:?#fff;
????z-index:?1;
}
這種方式對于第一種方式的缺點非常完美的解決了,但是這種方式對于頁面整體背景沒有強制要求顏色或圖片的還可以,但在我為“不小心”為body加了背景圖后,它就不行了、沒有效果了。(因為上面說了,這種方式實現的特點是同級z-index覆蓋偽元素的“偽頁面”)
這里面有個mix-blend-mode: ;,這是個非常好用的屬性 —— 規定被規定的元素和它下面的背景相比誰的顏色深就用誰的顏色!(就是這個玩意引起的問題)
★
這個小知識是筆者跟張鑫旭老師的 這篇文章() 學到的,嘿嘿,還挺好用
”
最后
點個在看支持我吧