利⽤CSS动画制作Html表格数据滚动显⽰
直接上图看最终实现效果:
DataV⾥有这个效果,看起来⾼⼤上,实际⾃⼰开发也不难实现。实现的⽅法很多,下⾯是本⼈的⼀种实现⽅案,分享给⼤家。
这个效果需要解决2个问题:
1:⾸尾的数据衔接;
2:css动画实现;
⾸先利⽤js 构造⼀些数据;
Html 结构如下:
<div class="table-title">
<span > 序号</span>
<span > 列2</span>
<span > 列3</span>
<span > 列4</span>
</div>
<div id="data-wrapper1" class="data-content">
</div>
js 构造⾏数据,奇数⾏和偶数⾏数据样式不⼀样⽽已:注意为了⾸尾衔接的特殊处理,就是在数据结束的尾部刻意追加⾸先开始的设定N⾏
数据;
var buildRow = function () {
var htmlTemplate = '<div class="{0}"><span class="td-col1">{1}</span><span class="td-col2"> xxx</span><span class="td-col3">⾏数据</span><span class=        var wrapper = $("#data-wrapper1");
for (var i = 0; i < 15; i++) {
var cls = "table-row-odd";
if (i % 2 === 0) {
cls = "table-row-even";
}
wrapper.append(htmlTemplate.format([cls, (i + 1).toString()]));
}
// 为了让⾸尾动画衔接上,在数据⾏的末尾追加开头的N⾏数据
for (var j = 0; j < rownumber; j++) {
cls = "table-row-odd";
if (j % 2 === 0) {
cls = "table-row-even";
}
wrapper.append(htmlTemplate.format([cls, (j+1).toString()]));
}
};
关键的部分就是Js实现了:
var startDataCollapse = function () {
var divs = $("#data-wrapper1").find("div");
var divlen = divs.length;
var scroll_total = il(divlen / rownumber);
var times = 1;
if (scroll_total > 1) {
setInterval(function () {
$.each(divs, function (i, itm) {
if (!$(itm).hasClass("data-collapse") && i < times * rownumber) {
$(itm).addClass("data-collapse");
}
});
if (times === scroll_total) {
times = 1;
$.each(divs, function (i, itm) {
$(itm).removeClass("data-collapse");
});
setTimeout(function () {
doDataCollapse();
}, 500);// 延迟执⾏刚好为 css动画的执⾏时间
} else {
times++;
}
}, 2000);
}
};
下⾯的这个函数作⽤为:当全部⾏css动画执⾏完后,最后⼀屏动画执⾏需要0.5s,所以延迟0.5s秒后
⽴即执⾏刚被还原的第⼀屏数据的动画,这样下⼀个time interval的时候直接就是从第⼆屏开始动画了,基于这个实现,⾸尾的动画就衔接上了。关键部分就在于此。
var doDataCollapse = function () {
var divsNew = $("#data-wrapper1").find("div");
$.each(divsNew, function (i, itm) {
if (!$(itm).hasClass("data-collapse") && i < rownumber) {
$(itm).addClass("data-collapse");
}
});
};
最后看下CSS动画实现部分:
/*#region Css collapse */
.data-content {
height: 250px;
overflow-y: hidden;
}
.table-title {
height: 50px;
line-height: 50px;
background-color: #2688e6;
font-size: 16px;
color: #fff;
}
.
data-content .table-row-even {
height: 50px;
line-height: 50px;
background-color: #002d36;
font-size: 0;
}
}
.data-content .table-row-odd {
height: 50px;
line-height: 50px;
background-color: #003e52;
font-size: 0;
}
.data-content .td-col1 {
display: inline-block;
width: 10%;
font-size: 16px;
color: #fff;
text-align:center;
}
.data-content .td-col2 {
display: inline-block;
width: 20%;
font-size: 16px;
color: #fff;
}
.data-content .td-col3 {
display: inline-block;
width: 30%;
font-size: 16px;
color: #fff;
}
.data-content .td-col4 {
display: inline-block;
width: 40%;
font-size: 16px;
color: #fff;
}
.data-collapse {
animation: data-col .5s;
animation-timing-function: ease;    animation-fill-mode: forwards;
overflow:hidden;
}
@keyframes data-col {
from {
height: 50px;
}
to {
height: 0;
}
}
/*#endregion */
更新:再来看⼀个vue版本的实现:
<div id="dataWrapper" class="data-content">
<div v-for="(f,index) in infos" :key="index" :class="index%2==0?'table-row-odd':'table-row-even'">                    <span class="td-col td2-col0">{{f.id}}</span>
<span class="td-col td2-col1">{{f.device}}</span>
<span class="td-col">{{f.content}}</span>
</div>
</div>
CSS部分
.data-content
height 410px
overflow-y hidden
.data-collapse
animation data-col 0.5s
animation-timing-function ease
animation-fill-mode forwards
overflow:hidden
@keyframes data-col
{
from{height:50px}
to{height:0}
}
.table-title-dark
height 48px
line-height 48px
background-color rgba(11,38,75,1)
font-size 16px
color #fff
.td-head
color white !important
font-weight bold
.table-row-odd
background-color rgba(0,62,82,0.5)
font-size 0
.table-row-even
background-color rgba(0,45,54,0.5)
font-size 0
.
td-col
display:inline-block
height 52px
line-height 52px
box-sizing border-box
font-size:16px
color:$displayTextColor
text-align:center
text-wrap:none
white-space:nowrap
text-overflow:ellipsis
overflow:hidden
&.td2-col0
width:15%
&.td2-col1
width:45%
Script部分
export default {
data(){
return {
infos:[
{id:'1',device:'xx1',content:'保养提醒',},
{id:'1',device:'xx1',content:'保养提醒',},
{id:'2',device:'xx2',content:'保养提醒',},
{id:'3',device:'xx',content:'保养提醒',},
{id:'4',device:'xx',content:'保养提醒',},
{id:'5',device:'xx',content:'保养提醒',},
{id:'6',device:'xx',content:'保养提醒',},
{id:'7',device:'xx',content:'保养提醒',},
{id:'8',device:'x',content:'保养提醒',},
{id:'9',device:'xxx',content:'保养提醒',},
{id:'10',device:'xx',content:'保养提醒',},
{id:'11',device:'xx',content:'保养提醒',},
{id:'12',device:'xx',content:'保养提醒',},
{id:'13',device:'xx',content:'保养提醒',},
],
rownumber:8
}
},
components:{
secheader,
},
methods: {
startLogDataCollapse: function () {
var divs = $("#dataWrapper").find("div");
var scroll_total = il(divs.length / wnumber);
var times = 1;
var rownum= wnumber;
// if (scroll_total > 1) {
setInterval(function () {
$.each(divs, function (i, itm) {
if (!$(itm).hasClass("data-collapse") && i < times * rownum) {                            $(itm).addClass("data-collapse");
}
});
if (times === scroll_total) {
times = 1;
$.each(divs, function (i, itm) {
$(itm).removeClass("data-collapse");
});
setTimeout(function () {
$.each(divs, function (i, itm) {
if (!$(itm).hasClass("data-collapse") && i < rownum) {                                    $(itm).addClass("data-collapse");
}
});
}, 500);
} else {
times++;
}
}, 3 * 1000);
// }
},
buildRow:function(){
html滚动效果代码var scroll_total = il(this.infos.length / wnumber);
var rowLeft = this.infos.length % wnumber;
var lastPageRow = wnumber - rowLeft;
for (var k = 0; k < lastPageRow; k++) {
this.infos.push({id: this.infos.length+k+1,device:'--',content:'--'})            }
var beginArr= this.infos.slice(wnumber);
for (var j = 0; j < wnumber; j++) {
this.infos.push(beginArr[j]);
}