直接上图看最终实现效果:
DataV里有这个效果,看起来高大上,实际自己开发也不难实现。实现的方法很多,下面是本人的一种实现方案,分享给大家。
这个效果需要解决2个问题:
1:首尾的数据衔接;
2:css动画实现;
首先利用js 构造一些数据;
Html 结构如下:
<div class="table-title">
<span style="display:inline-block; width:10%; text-align:center;"> 序号</span>
<span style="display:inline-block; width:20%; "> 列2</span>
<span style="display:inline-block; width:30%; "> 列3</span>
<span style="display:inline-block; width:30%; "> 列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="td-col4">示例数据</span></div>';
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 = Math.ceil(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 */
下载链接:https://download.csdn.net/download/elie_yang/11229191
更新:再来看一个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:'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 = Math.ceil(divs.length / this.rownumber);
var times = 1;
var rownum= this.rownumber;
// 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(){
var scroll_total = Math.ceil(this.infos.length / this.rownumber);
var rowLeft = this.infos.length % this.rownumber;
var lastPageRow = this.rownumber - rowLeft;
for (var k = 0; k < lastPageRow; k++) {
this.infos.push({id: this.infos.length+k+1,device:'--',content:'--'})
}
var beginArr= this.infos.slice(0,this.rownumber);
for (var j = 0; j < this.rownumber; j++) {
this.infos.push(beginArr[j]);
}
},
},
mounted:function(){
this.buildRow();
this.$nextTick(()=>{
this.startLogDataCollapse();
});
}
}