美文网首页
HTML+CSS实现进度条

HTML+CSS实现进度条

作者: 爱鸽子的玉米君 | 来源:发表于2016-08-22 16:39 被阅读6470次

    最近业务上有了产品预约进度条的需求,故学习已有的一些成熟方案,便捷掌握使用方法

    • 均分滚动条

    首先是网易云音乐的用户等级进度条


    网易云音乐进度条

    经过一番搬运整理,我们也可以实现间隔均分段的滚动条,代码中的图像文件来自网易云音乐用户等级页面,感兴趣的读者可到官网上拿取。
    以下为CSS样式

    <style>
        .sub {
            width: 100%;
            position: relative;
            z-index: 1;
            padding-top: 31px;
            height: 34px;
            overflow: hidden;
        }
        .sub .subbg {
            width: 835px;
            height: 10px;
            position: absolute;
            left: 0;
            bottom: 0;
            z-index: 2;
            border-radius: 10px;
            background: #dcdfe6;
        }
        .sub .subbg span {
            /*一条渐变线*/
            background: url(mylevelbar.png) 0 0 repeat-y;
            width: 100%;
            height: 10px;
            display: block;
            border-radius: 10px;
            -webkit-animation: subbar 2s;
            animation: subbar 2s;
        }
        .sub .subnum {
            width: 100%;
            height: 40px;
            left: 0;
            bottom: 0;
            position: absolute;
            z-index: 2;
        }
        .divison {
            position: absolute;
            left: 13px;
            bottom: 0;
            width: 100%;
            height: 10px;
        }
        .divison span {
            float: left;
            display: inline;
            width: 1px;
            background: #fff;
            height: 10px;
            margin-left: 80px;
        }
        .divnum {
            position: absolute;
            left: -40px;
            top: -20px;
            font-family: 'Microsoft YaHei';
            font-size: 18px;
            color: #c4c6cc;
            width: 980px;
        }
        .divnum li.z-ov {
            color: #ed5757;
            -webkit-animation: show 3s;
            animation: show 3s;
        }
        .divnum li {
            float: left;
            width: 25px;
            height: 28px;
            line-height: 24px;
            display: inline;
            margin-right: 56px;
            text-align: center;
        }
        li {list-style: none;}
        .divnum li.z-on {
            color: #fff;
            -webkit-animation: show1 2s;
            animation: show1 2s;
            background-position: 0 -50px;
        }
        .h3 em,
        .divnum li.z-on,
        .n-pow .telist li,
        .n-level i,
        .n-level-big i {
            /*此处的 0 -50px 和官网上的 0 9999px 有差异*/
            background: url(mylevel.png) no-repeat 0 -50px;
        }
        /*动画效果*/
        @keyframes subbar {
            0% {
                width: 0;
            }
            100% {
                width: 100%;
            }
        }
        @keyframes show {
            0% {
                color: #c4c6cc;
            }
            100% {
                color: #ed5757;
            }
        }
        @keyframes show1 {
            0% {
                color: #c4c6cc;
                background-position: 9999px 9999px;
            }
            50% {
                color: #c4c6cc;
                background-position: 0 -50px;
            }
            100% {
                color: #fff;
            }
        }
        </style>
    

    以下为HTML结构

    <!-- 网易云音乐web版进度条 -->
    <div class="sub">
        <div class="subbg">
            <!-- 通过js控制div的宽度实现进度条的进度,用动画控制前进效果 -->
            <div style="width:820.8666666666667px;"><span></span></div>
            <!-- /宽度为25+81x等级x70% -->
        </div>
        <div class="subnum">
            <div class="divison"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>
            <div class="divnum">
                <ul>
                    <li class="z-ov">0</li>
                    <li class="z-ov">1</li>
                    <li class="z-ov">2</li>
                    <li class="z-ov">3</li>
                    <li class="z-ov">4</li>
                    <li class="z-ov">5</li>
                    <li class="z-ov">6</li>
                    <li class="z-ov">7</li>
                    <li class="z-ov">8</li>
                    <li class="z-on">9</li>
                    <li class="">10</li>
                </ul>
            </div>
            <!-- / .ov已过等级样式 .on达到等级样式 -->
        </div>
    </div>
    

    最终效果

    效果图

    看完了均匀进度的进度条,分享一下不均匀进度的进度条,一个移动端demo

    • 不均分进度条

    <!doctype html>
    <html lang="en">
     <head>
      <meta charset="UTF-8">
      <title>我的等级</title>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0,maximum-scale=1.0, user-scalable=0" />
      <link rel="stylesheet" href="style.css">
      <style id="dynamic"></style>
      <script>
         var Config = {
            // 等级大图片url地址
            courierRankBigUrl:  'images/grade3-icon.png',
    
            // 配送员等级名称
            courierRankName: '3级鲜锋官',
    
            // 同时可接单数
            courierCanPackgeCountDoing:  '10',
    
            // 积分数组1,2,3,4,5;50,100,150,200,250
            integrationRankString:  '1,2,3,4,5;0,100,150,200,250',
    
            // 经验豆数组1,2,3,4,5;50,100,150,200,250
            experienceBeanRankString: '',
    
            // 本月累计积分
            monthCompletedWaybills:  '200'
         };
      </script>
      <script>
          function setStyle(obj,css){
             for(var i in css){
                obj.style[i] = css[i];
             }
         }
         // 将积分数组切成两块,并用split方法转换成数组
          var scores = Config.integrationRankString.split(";")[1].split(',');
          console.log((Config.integrationRankString.split(";")[1]));
          console.log( Config.integrationRankString.split(";")[1].split(',') instanceof Array);
    
          // 后台返回的积分
          var score = Config.monthCompletedWaybills;
            /*
             * 进度条的宽度百分比的计算方式设计如下:
             * 假如第一段50分 第二段100分 第三段300分  第四段500分 那么假如服务器返回的是375分,那么在浏览器下占比如下
             * 由于页面分了5段,每段显示20%的宽度; 遍历数组[50,100,300,500],定义一个遍历count = 0;
             * 如果数组任何一段小于服务器返回375的话,那么count自加1,因此count=3
             * 比例如下:(375 - 300) / (500 - 300) + 3 = 3/8 + 3 = 3.375; 最后 3.375 / 5 * 100%= 67.5%;
             * 记住 因为数组arrs去掉了第一项了 所以curNum要减去1 即:curNum - 1
             */
             /*
              * @todo 计算进度条的百分比
              * @param {score,arrs} 服务器返回的总分 服务器返回的数组
              */
             var count = 0;
             function percent(score,arrs) {
                var tempCount = 0;
                var percent;
                //  如果积分大于数组最后一个总积分的话, 那么进度条就是最大的
                if(score*1 > arrs[arrs.length -1] * 1) {
                    score = arrs[arrs.length -1];
                }
                for(var i = 0; i < arrs.length; i+=1) {
                    if(score*1 > arrs[i]*1) {
                        tempCount++;
                    }
                }
                count = tempCount;
                if(tempCount*1 < 1) {
                    percent = (score / arrs[0]) / 5 * 100;
                }else {
                    percent = ((score - arrs[tempCount - 1]) / (arrs[tempCount] - arrs[tempCount - 1]) + tempCount) / 5 * 100;
                }
    
                return percent + "%";
             }
             if(scores[0] == 0) {
                scores.shift();
             }
             // 返回第五段的值 计算方法 val fiveVal = arrs[arrs.length - 1] * 2
             var fiveVal = scores[scores.length - 1] * 2 + "";
             scores.push(fiveVal);
    
             var width = percent(score,scores);
    
             var dynamic = document.getElementById("dynamic");
             dynamic.innerHTML = '@-webkit-keyframes load {0% {width: 0%;}100% {width: '+width+';}}';
    
             window.onload = function(){
                var bar = document.getElementById("progress-bar");
                setStyle(bar,{width:width});
             }
      </script>
     </head>
     <body>
        <div class="myGrade-container">
            <div class="myGrade-header">
                <p class="grade-img" id="grade-img"></p>
                <p class="grade-desc" id="courierRankName">二级鲜锋官</p>
                <p class="grade-amount">可同时接单数<i id="grade-amount">2</i>单</p>
            </div>
            <div class="myGrade-progress-bar">
                <h4>本月升级进度</h4>
                <div class="myGrade-integral">
                    <div class="maGrade-wrap">
                        <h3 id="minMonthScore">本月累计积分<i id="monthScore">(97分)</i></h3>
                        <div class="progress-bar-inner">
                            <div class="progree-nums" id="progree-nums">
                                <!--
                                <span>1级</span>
                                <span>2级</span>
                                <span>3级</span>
                                <span>4级</span>
                                <span>5级</span>
                                -->
                            </div>
                            <div id="progress-box" class="progress-box">
                                <div class="division-bar" id="division-bar">
                                    <span class="pbar w20"></span>
                                    <span class="pbar w40"></span>
                                    <span class="pbar w60"></span>
                                    <span class="pbar w80"></span>
                                </div>
                                <div id="progress-bar" class="progress-bar">
                                </div>
                                <div></div>
                            </div>
                            <div class="progress-score" id="progress-score">
                                <!--
                                <i>0</i>
                                <span>50分</span>
                                <span>100分</span>
                                <span>300分</span>
                                <span>500分</span>
                                -->
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <p class="myGrade-state">本月累计获得的积分决定下月的等级</p>
            <ul class="myGrade-list">
                <li id="show-grade">查看等级特权<i></i></li>
                <li id="how-grade">如何提升等级<i></i></li>
            </ul>
        </div>
    
        <script>
            function $Id(id){
                return document.getElementById(id);
            };
            function hasClass(obj, cls) {
                return obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
            }
    
            function addClass(obj, cls) {
                if (!hasClass(obj, cls)) obj.className += " " + cls;
            }
            var bar = $Id("progress-bar"),                 // 进度条id
                gradeImg = $Id("grade-img"),               // 等级图片icon
                courierRankName = $Id("courierRankName"),  // 配送员等级名称
                gradeAmount = $Id("grade-amount"),         // 可同时接单数
                monthScore = $Id("monthScore"),            // 本月累计积分
                scoreGrade = $Id("progree-nums"),          // 等级id
                progressScore = $Id("progress-score"),     // 积分id
                divisionBar = $Id("division-bar");         // 进度条分隔条
    
            // 服务器返回的等级图片
            gradeImg.style.backgroundImage="url("+Config.courierRankBigUrl+")";
    
            // 服务器返回的等级名称
            courierRankName.innerHTML = Config.courierRankName;
    
            // 可同时接单数
            gradeAmount.innerHTML = Config.courierCanPackgeCountDoing;
    
            // 本月累计积分
            monthScore.innerHTML = "(" + Config.monthCompletedWaybills + "分" + ")";
            if(Config.monthCompletedWaybills *1 < 0) {
                var minMonthScore = $Id("minMonthScore");
                if(!hasClass(minMonthScore,'current')) {
                    addClass(minMonthScore,'current');
                }
            }
            // 服务器返回的等级和积分数组
            var grades = Config.integrationRankString.split(";")[0].split(','),
                scores = Config.integrationRankString.split(";")[1].split(','),
                gradesHTML = '';
                scoresHTML = '';
            for(var i = 0; i < grades.length; i++) {
                gradesHTML += '<span>'+grades[i]+'级</span>';
            }
            scoreGrade.innerHTML = gradesHTML;
            for(var j = 0; j < scores.length; j++) {
                if(j == 0) {
                    scoresHTML += '<i>'+scores[j]+'</i>';
                }else {
                    scoresHTML += '<span>'+scores[j]+'分</span>';
                }
            }
            progressScore.innerHTML = scoresHTML;
            var divisionBarSpans = divisionBar.getElementsByTagName("span");
            // 后台返回的积分
            var score2 = Config.monthCompletedWaybills;
    
            var curIndex = scores.indexOf(score2);
            if(count*1 > 0) {
                 for(var i = 0; i < count; i++) {
                    if(!hasClass(divisionBarSpans[i],'current')) {
                        // 比如返回积分是200 正好数组也有200这个积分 正好相等的话 ,那么就不添加current类名
                        if(i !== curIndex) {
                            (function(i){
                                setTimeout(function(){
                                    addClass(divisionBarSpans[i],'current');
                                },2500);
                            })(i)
                        }
                    }
                 }
            }
        </script>
     </body>
    </html>
    

    css 样式

    // css reset
    body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{margin:0;padding:0;font-family:"Microsoft yahei";color:#000;}
         ul,ol,li{list-style:none;}
         i,em{font-style:normal}
         img{max-width:100%;}
         html{font-size:62.5%;}
         html,body{background:#f5f5f5;}
    
         .myGrade-container {width:100%;background:#f5f5f5;}
         .myGrade-header {width:100%;margin-top:20px;border-top:1px solid #d7d7d7;border-bottom:1px solid #d7d7d7;text-align:center;background:#fff;padding:18px 0 20px 0;}
         .grade-img {background-repeat:no-repeat;background-size:66px 66px;width:66px;height:66px;margin:0 auto;}
         .grade-desc {padding:12px 0;color:#fc6605;}
         .grade-amount {font-size:1em;font-family:"Microsoft yahei";}
         .grade-amount i{padding-left:4px;}
         .myGrade-progress-bar {width:100%;}
         .myGrade-progress-bar h4{color:#707070;font-size:1.125em;font-weight:500;padding-left:10px;padding-top:30px;}
         .myGrade-integral {border-top:1px solid #d8d7d8;border-bottom:1px solid #d8d7d8;background:#fff;margin-top:8px;}
         .maGrade-wrap {width:90%;margin:0 auto;padding-bottom:20px;}
         .myGrade-integral h3{font-size:1.125em;font-weight:500;padding:16px 0;}
         .myGrade-integral h3 i{color:#81bb3b;}
         .progress-bar-inner {position:relative;}
         .progree-nums {width:100%;font-size:0;overflow:hidden;}
         .progree-nums span,.progress-score span{float:left;display:inline-block;width:20%;text-align:center;color:#757575;}
         .progress-box{position:relative;height:16px;border:1px solid #a0db58;border-radius:30px;margin-top:5px;}
         .progress-bar{position:absolute;left:0;top:0;height:16px;background:#a0db58;border-radius:30px;z-index:9;}
    
         .division-bar {position:absolute;left:0;top:0;width:100%;z-index:11;}
         .division-bar .pbar {position:absolute;height:16px;background-color:#a0db58;left:20%;width:1px;}
         .division-bar .w20 {left:20%;}
         .division-bar .w40 {left:40%;}
         .division-bar .w60 {left:60%;}
         .division-bar .w80 {left:80%;}
    
         .progress-score {position:relative;margin-top:5px;font-size:0;overflow:hidden;}
         .progress-score span{text-align:right;}
         .progress-score i{position:absolute;left:0;top:0;color:#757575;}
         .myGrade-state {width:95%;height:50px;padding-left:5%;margin-top:15px;background:#f5f5f5;color:#707070;border-bottom:1px solid #d8d7d8;}
         .myGrade-list li{width:95%;padding-left:5%;background:#fff;border-bottom:1px solid #d8d7d8;height:60px;line-height:60px;}
         .myGrade-list li i{float:right;padding-right:4%;background:url("images/arrow.png") no-repeat;width:10px;height:17px;background-size:10px 17px;margin-top:22px;}
    
    
         /* 当前加粗 */
         .progree-nums span.current{font-weight:700;color:#212121;}
         .division-bar span.current{background-color:#fff;}
         .myGrade-integral h3.current,.myGrade-integral h3.current i{color:#f44336;}
         /* 媒体查询 */
         .grade-desc{font-size:1.8rem;}
         .grade-amount{font-size:1.6rem;}
         .myGrade-progress-bar h4{font-size:1.5rem;}
         .myGrade-integral h3{font-size:1.6rem;}
         .progree-nums span,.progress-score span{font-size:1.5rem;}
         .myGrade-state {font-size:1.5rem;}
         .myGrade-list li {font-size:1.8rem;}
         .progress-score i{font-size:1.5rem;}
         @media (min-width:360px) and (max-width: 399px) {
    
         }
         @media (min-width: 320px) and (max-width:359px){
            .progress-score i,.progress-score span{font-size:1.3rem;}
         }
    
         .progress-bar {background:-webkit-gradient(linear, 0 0, 0 100%,from(#a0db58),to(#a0db58));-webkit-animation: load 3s ease-out 1;}
    

    完成效果

    完成效果

    移动端的demo来自网络,这个demo涉及到了进度条的动态实现,代码比较长比较复杂,实现不均匀进度。

    相关文章

      网友评论

          本文标题:HTML+CSS实现进度条

          本文链接:https://www.haomeiwen.com/subject/zwfgsttx.html