純前端 - 各種實現進度條
進度條是一個很是常見的功能,實現起來也不難,通常我們會用 div
來實現。做為一個這麼常見的需求,這篇就要來康康有哪些,以純前端有哪些有意思的方式來實現進度條。javascript
基礎版 - div
ps. (這邊如下 gif 周圍稍有些瑕疵,我也不知道甚麼問題,使用的是 python 的 moviepy 庫由 MP4 生成 gif。如有解決辦法還請多多指教啦!):css
馬上就來看看實際效果:
html
這種方法的做法就是以當前 <div>
為容器,以 ::before
為內容填充。用 <div>
的好處就是實現簡單,不過缺點就是標籤語義化不高,不容易維護修改。代碼實現以下:前端
<!-- html code --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>process demo</title> <link rel="stylesheet" href="process1.css"> </head> <body> <div id="process-1" class="process-1"></div> <button id="btn-1" class="btn-1">click me!</button> <script type="text/javascript" src="process1.js"></script> </body> </html>
/* css code */ * { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; margin: 10px; } .process-1 { height: 30px; width: 300px; background-color: #f5f5f5; border-bottom-right-radius: 10px; border-top-right-radius: 10px; } .process-1::before { counter-reset: progress var(--percent); content: counter(progress) '%\2002'; width: calc(300px * var(--percent, 0) / 100); display: block; height: 30px; line-height: 30px; font-size: 13px; color: #fff; background-color: #2486ff; text-align: right; border-bottom-right-radius: 10px; border-top-right-radius: 10px; } .btn-1 { margin-top: 15px; }
// js code let startTime = (new Date()).getTime(); let currentPercentage = 0; let maxPercentage = 100; let countDelay = 50; let timerId = null; const percentageChange = () => { let currentTime = (new Date()).getTime(); if (currentTime - startTime >= countDelay) { currentPercentage++; startTime = (new Date()).getTime(); document.getElementById("process1").style = `--percent: ${ currentPercentage}`; } if (currentPercentage < maxPercentage) { timerId = window.requestAnimationFrame(percentageChange); }else { window.cancelAnimationFrame(timerId); } } document.getElementById("btn1").addEventListener('click', percentageChange);
進階版 - input
馬上就來看看實際效果:
java
這種方法是利用了 HTML5 為 input
這個標籤提供了 range
這個新的屬性。其中,還要配合 step
, min
, max
, value
進行實現。基本上代碼和 div
的實現大同小異。代碼實現以下:python
<!-- html code --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>process2 demo</title> <link rel="stylesheet" href="process2.css"> </head> <body> <input id="process2" class="process2" type='range' step="1" min="0" max="100" value="0"/> <button id="btn2" class="btn2">click me!</button> <script type="text/javascript" src="process2.js"></script> </body> </html>
/* css code */ * { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; margin: 10px; } .process2 { display: block; height: 20px; width: 300px; background-color: #2376b7; } .btn2 { margin-top: 15px; }
// js code let startTime = (new Date()).getTime(); let currentPercentage = 0; let maxPercentage = 100; let countDelay = 50; let timerId = null; const percentageChange = () => { let currentTime = (new Date()).getTime(); if (currentTime - startTime >= countDelay) { currentPercentage++; startTime = (new Date()).getTime(); document.getElementById("process2").value = currentPercentage; document.getElementById("process2").style.background = `linear-gradient(#2376b7 ${ currentPercentage}%, #FFF 0%`; } if (currentPercentage < maxPercentage) { timerId = window.requestAnimationFrame(percentageChange); }else { window.cancelAnimationFrame(timerId); } } document.getElementById("btn2").addEventListener('click', percentageChange);
高級版 - progress
除了上述兩種方式模擬之外,當然 whatwg (World Hypertext Application Technology Working Group) 有為我們提供原生的進度條標籤,那就是 progress
。先來看看實際果:
web
這種方式就是用 whatwg 為我們提供的 progress
標籤,十分方便,通過在 css 中對標籤設置 -webkit-appearance: none;
也能夠自定義標籤的樣式,還算靈活方便的。具體代碼實現以下:app
<!-- html code --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>process3 demo</title> <link rel="stylesheet" href="process3.css"> </head> <body> <progress id="process3" class="process3" max="100" value="0"></progress> <button id="btn3" class="btn3">click me!</button> <script type="text/javascript" src="process3.js"></script> </body> </html>
/* css code */ * { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; margin: 10px; } .process3 { display: block; width: 300px; height: 30px; -webkit-appearance: none; } .process3::-webkit-progress-bar { background-color: gainsboro; } .process3::-webkit-progress-value { background: linear-gradient( -45deg, transparent 33%, rgba(0, 0, 0, .1) 33%, rgba(0,0, 0, .1) 66%, transparent 66% ), linear-gradient( to top, rgba(255, 255, 255, .25), rgba(0, 0, 0, .25) ), linear-gradient( to left, #09c, #f44); } .btn3 { margin-top: 15px; }
// js code let startTime = (new Date()).getTime(); let currentPercentage = 0; let maxPercentage = 100; let countDelay = 50; let timerId = null; const percentageChange = () => { let currentTime = (new Date()).getTime(); if (currentTime - startTime >= countDelay) { currentPercentage++; startTime = (new Date()).getTime(); document.getElementById("process3").setAttribute("value", currentPercentage); } if (currentPercentage < maxPercentage) { timerId = window.requestAnimationFrame(percentageChange); }else { window.cancelAnimationFrame(timerId); } } document.getElementById("btn3").addEventListener('click', percentageChange);
終極版 - meter
最後介紹也能實現進度條的一種方式,那就是 meter
標籤。直接先看效果:
spa
能夠看到,meter
標籤也能實現類似進度條的功能。如上圖也注意到顏色有變化,這是因為 meter
中的 low
和 high
屬性設定,具體有興趣能夠百度,很簡單的!具體代碼實現以下:code
<!-- html code --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>process4 demo</title> <link rel="stylesheet" href="process4.css"> </head> <body> <meter id="process4" class="process4" low="60" high="80" min="0" max="100" value="0"></meter> <button id="btn4" class="btn4">click me!</button> <script type="text/javascript" src="process4.js"></script> </body> </html>
/* css code */ * { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; margin: 10px; } .process4 { display: block; width: 300px; height: 30px; } .btn4 { margin-top: 15px; }
// js code let startTime = (new Date()).getTime(); let currentPercentage = 0; let maxPercentage = 100; let countDelay = 50; let timerId = null; const percentageChange = () => { let currentTime = (new Date()).getTime(); if (currentTime - startTime >= countDelay) { currentPercentage++; startTime = (new Date()).getTime(); document.getElementById("process4").setAttribute("value",currentPercentage); } if (currentPercentage < maxPercentage) { timerId = window.requestAnimationFrame(percentageChange); }else { window.cancelAnimationFrame(timerId); } } document.getElementById("btn4").addEventListener('click', percentageChange);