滚动条滚动

自动化滚动实现

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

需求图:


滚动条滚动_第1张图片
p6.jpg

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

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

HTML的代码

大致的意思就是通过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;
  }
}

实际的效果如下图所示:


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

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

 
{{item.stepLog}}

这是个日志,会随着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


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

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

你可能感兴趣的:(滚动条滚动)