8

純前端 - 各種實現進度條

 3 years ago
source link: https://blog.csdn.net/weixin_46803507/article/details/111397424
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

進度條是一個非常常見的功能,實現起來也不難,一般我們會用 div 來實現。作為一個這麼常見的需求,這篇就要來康康有哪些,以純前端有哪些有意思的方式來實現進度條。

基礎版 - div

ps. (這邊以下 gif 周圍稍有些瑕疵,我也不知道甚麼問題,使用的是 python 的 moviepy 庫由 MP4 生成 gif。若有解決辦法還請多多指教啦!):

馬上就來看看實際效果:

84db1c4474ab57144527e73e57e5c342.gif

這種方法的作法就是以當前 <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

馬上就來看看實際效果:

cb92d47dcff9a5d2bae52b41fc52a24b.gif

這種方法是利用了 HTML5 為 input 這個標籤提供了 range 這個新的屬性。其中,還要配合 step, min, max, value 進行實現。基本上代碼和 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>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。先來看看實際果:

f34203f3f438516a871bc045c9083fe0.gif

這種方式就是用 whatwg 為我們提供的 progress 標籤,十分方便,通過在 css 中對標籤設置 -webkit-appearance: none; 也可以自定義標籤的樣式,還算靈活方便的。具體代碼實現如下:

<!-- 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 標籤。直接先看效果:

0c361cbff41aad029b9b09a8542e4553.gif

可以看到,meter 標籤也能實現類似進度條的功能。如上圖也注意到顏色有變化,這是因為 meter 中的 lowhigh 屬性設定,具體有興趣可以百度,很簡單的!具體代碼實現如下:

<!-- 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);

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK