純前端 - 各種實現進度條

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

基礎版 - div

ps. (這邊以下 gif 周圍稍有些瑕疵,我也不知道甚麼問題,使用的是 python 的 moviepy 庫由 MP4 生成 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

馬上就來看看實際效果:

這種方法是利用了 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。先來看看實際果:

這種方式就是用 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 標籤。直接先看效果:

可以看到,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);

猜你喜欢

转载自blog.csdn.net/weixin_46803507/article/details/111397424
今日推荐