如何使用JavaScript制作动态进度条

时间:2018-12-26 10:51:56

标签: javascript progress-bar

使用javascript制作动画动态滚动条的问题

我尝试制作一个动态动画进度条,当我通过使用onscroll事件到达特定的div时,它将运行该进度条,但是我无法达到我的目标,因为我觉得for循环和setInterval事件!

    //HTML
    <div class="skills_bars">
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>

    </div>


    //CSS 
 .skills_bars .meter{
   width: 100%;
   background: #000000;
   height: 11px;
   position: relative;
   display: block;
   margin-bottom:60px;
 }

.skills_bars .meter span:first- 
of-type{
  position: absolute;
  top: 0px;
  left: 0px;
  width: 10%;
  height: 100%;
  background: #FC4444;
  transition: all 1s ease-in-out;

}

.skills_bars .meter span.number{
  position: absolute;
  right: 3px;
  top: -29px;
  font-weight: bold;
  color: #fff;
  font-size: 18px;
  transition: all 1s ease-in-out;
}

    //JS CODE
    var progressMeter = document.querySelectorAll(".skills_bars 
                        .meter span:first-of-type");
    var progressNumber = document.querySelectorAll('.skills_bars 
                         .meter span.number');
    var progressNumberWidths = [50,90,80,20];

    window.addEventListener("scroll", progressNumberAdd);

    function progressNumberAdd(){
        if (pageYOffset > (progressMeter[0].offsetTop - 600)){
            window.removeEventListener("scroll", 
            progressNumberAdd);
            for(var i = 0; i < progressMeter.length; i++){
                        x(i);
            }
        }
    }

    function x(i){
        var move = setInterval(numberAddCheker(i), 15);
    }

    var width = 0;
    function numberAddCheker(i){

        if(width >= progressNumberWidths[i]){
            clearInterval(move)
        }else{
            width++;
            console.log(width)
            progressMeter[i].style.width = width + "%";
            progressNumber[i].textContent = width * 1 + "%" ;
        }
    } 

2 个答案:

答案 0 :(得分:0)

我没有您正在使用的CSS,因此我使用了自己的CSS,并做了一些小的改动,而不是逻辑上的改动,看来它正在起作用。请找到下面的代码,让我知道它是否适合您。 完成的更改:

  1. 添加了CSS
  2. 添加了progressMeter [i] .style.backgroundColor =“ blue”;
  3. 更改滚动以单击(需要更改)

注意:我仅在面对系统中的滚动条时才通过单击进行了测试。请对滚动事件进行测试,并告知我。

谢谢!

<!DOCTYPE html>
<html>
<head>
    <title>To test progress bar</title>
    <style type="text/css">
        .skills_bars {
            width: 280px;
            height: 5px;
        }
        .skills_bars .meter {
            display: inline-block;
            height: 5px;
            width: 200px;
            background-color: rgb(238, 238, 238);
            position: relative;
        }

        .skills_bars .meter span{
            display: inline-block;
            height: 5px;
            float: left;
        }
    </style>
 </head>
 <body>
     <div class="skills_bars">
         <div class="meter">
             <span "></span>
             <span class="number">10</span>
         </div>
         <div class="meter">
             <span></span>
             <span class="number">10</span>
         </div>
         <div class="meter">
             <span ></span>
             <span class="number">10</span>
         </div>
         <div class="meter">
             <span ></span>
             <span class="number">10</span>
         </div>
     </div>

    <script type="text/javascript">
    //JS CODE
        var progressMeter = document.querySelectorAll(".skills_bars .meter span:first-of-type");
        var progressNumber = document.querySelectorAll('.skills_bars .meter span.number');
        var progressNumberWidths = [50,90,80,20];

        window.addEventListener("click", progressNumberAdd);

        function progressNumberAdd(){
            if (pageYOffset > (progressMeter[0].offsetTop - 600)){
                window.removeEventListener("scroll", progressNumberAdd);
                for(var i = 0; i < progressMeter.length; i++){
                    x(i);
                }
            }
        }

        function x(i){

            var move = setInterval(numberAddCheker(i), 15);
        }

        var width = 0;
        function numberAddCheker(i){

            if(width >= progressNumberWidths[i]){
                clearInterval(move)
            }else{
                width++;
                console.log(width)
                progressMeter[i].style.width = width + "%";
                progressMeter[i].style.backgroundColor = "blue";

                progressNumber[i].textContent = width * 1 + "%" ;
            }
        }      
    </script>

    </body>
    </html>

答案 1 :(得分:0)

您的代码有两个问题,主要是在此行setInterval(numberAddCheker(i), 15)上,setInterval需要回调,这里您正在执行numberAddChecker。您可以像这样setIntervalsetInterval(numberAddCheker, 15, i)上的回调函数中传递参数。

您正在使用move清除间隔,但它不是全局变量,而是在内部声明的,因此当最终执行numberAddCheker move时将是不确定的,而您只是清除间隔最后一项。

您必须将所有间隔保存在数组中,并根据其索引清除它们。

这是一个完整的解决方案-

var progressMeter = document.querySelectorAll(".skills_bars .meter span:first-of-type");
    var progressNumber = document.querySelectorAll('.skills_bars .meter span.number');
    var progressNumberWidths = [50,90,80,20];
    var moveTimers = [];
    var width = 0;
    window.addEventListener("scroll", progressNumberAdd);

    function progressNumberAdd(){
        if (window.pageYOffset > (progressMeter[0].offsetTop - 600)){
            window.removeEventListener("scroll", progressNumberAdd);
            initProgressBar();
        }
    }
    
    function initProgressBar(){
      for(var i = 0; i < progressMeter.length; i++){
        x(i);     
      }  	
    }

    function x(i){
        moveTimers[i] = setInterval(numberAddCheker, 15, i);
    }
    
    function numberAddCheker(i){
        if(width >= progressNumberWidths[i]){
            clearInterval(moveTimers[i])
        }else{
            width++;
            progressMeter[i].style.width = width + "%";
            progressNumber[i].textContent = width * 1 + "%" ;
        }
    } 
 .skills_bars .meter{
   width: 100%;
   background: #000000;
   height: 11px;
   position: relative;
   display: block;
   margin-bottom:60px;
 }
body{
  background: #ccc;
}
.skills_bars .meter span:first-of-type{
  position: absolute;
  top: 0px;
  left: 0px;
  width: 10%;
  height: 100%;
  background: #FC4444;
  transition: all 1s ease-in-out;

}

.skills_bars .meter span.number{
  position: absolute;
  right: 3px;
  top: -29px;
  font-weight: bold;
  color: #fff;
  font-size: 18px;
  transition: all 1s ease-in-out;
}
   <div class="skills_bars" style="margin-top: 100vh">
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>
        <div class="meter">
            <span></span>
            <span class="number">10</span>
        </div>

    </div>

注意。为了清楚起见,我将for循环移到了一个单独的函数中,您可以将其保留在代码中。 仅供参考,滚动查看进度条。