美文网首页
滚动条滚动

滚动条滚动

作者: holy俊辉 | 来源:发表于2017-11-10 19:50 被阅读54次

    自动化滚动实现

    需求:实现一个自动化履历,页面加载,页面头部是信息栏,有状态显示和状态转动时间,出品人,开始时间,结束时间是自动化完成后显示。
    下面是每一步骤的滚动,在每一步骤滚动前,需要有状态转动,有状态转动的时间,随着时间的滚动,日志显示,日志随着内容滚动,展示最新的日志,步骤完成,状态显示完成的,步骤计时器停止,步骤向上滚动一定的距离。

    需求图:


    p6.jpg

    思路:
    一. 首先解决状态转动效果,这个可以写css,完成后覆盖即可
    二. 解决每一步骤完成后向上滚动一内容的高度,同理解决日志的问题
    三.解决每个步骤的计时器。

    实现需求:
    1.先解决状态转动的效果
    这一部分就是完全是css解决,利用css动画

    HTML的代码

    <div class="main-load-effect"
           ng-class="{successLoading:(autos.datasets.flowStatus=='Success'), failedLoading: (autos.datasets.flowStatus=='fail'),
                     startLoading:(autos.datasets.flowStatus == 'Running')}">
                     <span></span>
                     <span></span>
                     <span></span>
                     <span></span>
                     <span></span>
                     <span></span>
                     <span></span>
                     <span></span>
    </div>
    

    大致的意思就是通过span变为圆形,通过改变透明度来实现转动
    css的代码

    //头部转圈样式
    //这个是一个容器
    .main-load-effect {
      width:30px;
      height:30px;
      display: inline-block;
      vertical-align: middle;
      line-height: 40px;
      position:relative;
    
    }
    .main-load-effect span {
      display:inline-block;
      width:5px;
      height:5px;
      border-radius:50%;
      background:#48a5f4;
      position:absolute;
      -webkit-animation:loading 1.04s ease infinite;
    }
    // 通过 改变透明度实现转动效果
    @-webkit-keyframes loading {
      0% {
        opacity:1;
      }
      100% {
        opacity:0.2;
      }
    }
    .main-load-effect span:nth-child(1) {
      left:0px;
      top:50%;
      margin-top:-2.5px;
      -webkit-animation-delay:0.13s;
    }
    .main-load-effect span:nth-child(2) {
      left:3px;
      top:5px;
      -webkit-animation-delay:0.26s;
    }
    .main-load-effect span:nth-child(3) {
      left:50%;
      top:0px;
      margin-left:-2.5px;
      -webkit-animation-delay:0.39s;
    }
    .main-load-effect span:nth-child(4) {
      top:5px;
      right:3px;
      -webkit-animation-delay:0.52s;
    }
    .main-load-effect span:nth-child(5) {
      right:0px;
      top:50%;
      margin-top:-2.5px;
      -webkit-animation-delay:0.65s;
    }
    .main-load-effect span:nth-child(6) {
      right:3px;
      bottom:5px;
      -webkit-animation-delay:0.78s;
    }
    .main-load-effect span:nth-child(7) {
      bottom:0px;
      left:50%;
      margin-left:-2.5px;
      -webkit-animation-delay:0.91s;
    }
    .main-load-effect span:nth-child(8) {
      bottom:5px;
      left:3px;
      -webkit-animation-delay:1.04s;
    }
    //头部转动结束
    //最终样式
    .successLoading {
      width:25px;
      height: 25px;
      background: green;
      border-radius: 50%;
      span{
        display: none;
      }
    }
    .failedLoading {
      width:25px;
      height: 25px;
      background: red;
      border-radius: 50%;
      span{
        display: none;
      }
    }
    

    实际的效果如下图所示:


    image.png
    1. 完成滚动条
      完成滚动是需要滚动条滚动,js有滚动条事件,scroll()事件
      $(selector).scroll(function) 是scrolld的语法,function是触发的函数当滚动条滚动触发的函数,
      如:
    $("div").scroll(
        function(){
            console.log(" 我滚啦");
    }
    )
    

    当滚动条滚动就会打印出:“我滚啦”
    也可以设置滚动条的初始高度 scrollTop
    Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数。一个元素的 scrollTop 是可以去计算出这个元素最高高度距离它容器顶部的可见高度。当一个元素的容器没有产生垂直方向的滚动条,那它的 scrollTop 的值默认为0.
    也就是说需要一个容器,需要给容器设置一个高度,只有内容过多,超过容器的高度才会出现滚动条,

     <div class="logAutoScroll" style="width:100%; height:80%;overflow-y: auto;" >
                <div class="logAutoContent">
                  {{item.stepLog}}
                </div>
    </div>
    

    这是个日志,会随着stepLog的内容,填充容器,如果需要设置日志始终随着日志的滚动而滚动,只需要设置

    var oLog =document.getElementsByClassName("logAutoScroll")[i];
    var oLogContent =document.getElementsByClassName("logAutoContent")[i];
    $(oLog).scrollTop(oLogContent.scrollHeight);
    

    Element.scrollHeight 是计量元素内容高度的只读属性,包括overflow样式属性导致的视图中不可见内容。没有垂直滚动条的情况下,scrollHeight值与元素视图填充所有内容所需要的最小值clientHeight相同。包括元素的padding,但不包括元素的margin.
    这样就可以一直设置为滚动条随着内容滚动

    判定元素是否滚动到底

    如果元素滚动到底,下面等式返回true,没有则返回false.

    element.scrollHeight - element.scrollTop === element.clientHeight


    image.png
    1. 解决每个步骤的计时器
      a.这个比较麻烦,因为工程使用的是angular,每一个步骤使用的是ng-repeat,也就是一个变量使用,如果改变一个变量,这样所有的步骤都会改变,这就需要给每一个步骤重新赋值一个变量,刚开始是这样想的,但是楼主技术不行,不会给每个步骤赋值一个新的不同的变量,请教一个大神才知道。
      可以写一个方法,把每个步骤的序号或者$index传进去,然后返回一个变量。这个变量也是动态生成的。
      动态生成变量:
    self.datasets.steps.length这个是需要多少变量的长度
      //生成动态变量
                for(var j=0;j<self.datasets.steps.length;j++){
                    self["step"+(j+1)] = 0;
                }
    

    ng-repeat 中的变量是这样的 {{autos.getStepNum($index)}}
    这样就是把$index 传进去的,在getStepNum()这个方法中这样写

          //根据stepsIndex动态返回相应的变量
                self.getStepNum = function (row) {
                    console.log("row",row);
                    switch(row) {
                        case row:
                            return self["step"+row];
                    }
                };
    

    这样就会得到几个不同的变量,分别是

    self.step0
    self.step1
    self.step2
    self.step3
    self.step4
    

    每个步骤的计时器只需要赋给对应的变量就行了,不会相互影响
    计时器的计算,无非就是使用 setInterval使的一个变量一直增加
    setInterval 有几种写法,我感觉是比较迷惑人的,一种是在内部直接写的

    var time = setInterval(function(){
        self["step"]++;
        $scope.$evalAsync();
    },1000);
    

    另一种是需要写成函数的形式

    var time = setInterval(data,1000);
                function data(){
                    self["step"]++;
                    $scope.$evalAsync();
                }
    

    没有哪个是最好的,看个人喜好就可,上面的代码也正是定时器的写法,只不过写的简单些,每个步骤并未赋值一个刚才创建的变量。
    化秒为分和小时

                                //self["timer"+(i+1)] 就是得到的秒数
                               var theSecond=parseInt(self["timer"+(i+1)]);
                                var theMinute=0;
                                var theHour=0;
                                if(theSecond>60){
                                    theMinute=parseInt(theSecond/60);
                                    theSecond=parseInt(theSecond%60);
    
                                    if(theMinute>60){
                                        theHour=parseInt(theMinute/60);
                                        theMinute = parseInt(theMinute%60);
                                    }
                                }
    
                                self["step"+(i+1)]=""+parseInt(theSecond);
                                $scope.$evalAsync();
                                if(theMinute>0){
                                    self["step"+(i+1)]=""+parseInt(theMinute)+"分"+self["step"+(i+1)];
                                    $scope.$evalAsync();
                                }
                                if(theHour>0){
                                    self["step"+(i+1)]=""+parseInt(theHour)+"小时"+self["step"+(i+1)];
                                    $scope.$evalAsync();
                                }
    
    

    在这里面也有一段逻辑要思考,就是如何判断每个步骤正在跑或者已经完成,这就需要循环每个步骤的状态了,如果显示一个步骤正在跑,那么就启动计时器,日志开始滚动,如果每个步骤已经完成,就清除定时器,然后向上滚动一段距离,当所有的步骤都已经完成,再清除主定时器,或者失败也要清除主定时器,这段代码较长,在此不做粘贴,所有的代码已经上传到codepen

    https://codepen.io/holyjunhui/pen/YENWaR

    相关文章

      网友评论

          本文标题:滚动条滚动

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