最近做项目(vue系列)遇到两个需求,这里做一个记录,分享给大家。
原生Table列表实现轮询
需求:
- 当table列表数量较少时不轮询,超过一定高度才轮询;
- 鼠标移入暂停轮询,移出继续轮询
首先,原型图长下面这样:
右下角有个分页,用的是elementUI的分页组件,改了下样式,主体就是一个原生table
轮询有好几种实现方式,网上搜一搜很多,我这里使用js的方式实现,大概的思路就是:通过控制margin-top,比如margin-top=-1px,margin-top=-2px;margin-top=-3px;...,当这个值大于行高时,说明这条数据已经滚动完毕了,这时恢复margin-top=0,并且将它插入到tbody底部,从而实现轮询。直接上代码:
HTML
<div class="network-container">
<div class="network-center">
<img src="./imgs/img_map_bg_02.png" />
<img src="./imgs/img_map_bg_04.png" />
<div class="network-center-content">
<table class="deviceInfoBox">
<thead>
<tr>
<th class="name">设备类型</th>
<th class="name">设备大类</th>
<th class="code">设备编号</th>
<th class="pos">设备位置</th>
<th class>任务延时</th>
<th class="sysState">设备状态</th>
<th class="pro">任务完成进度</th>
<th class="pro">任务开始时间</th>
<th class="pro">任务结束时间</th>
<th class="pro">任务时长</th>
</tr>
</thead>
</table>
<div class="scroll-box" ref="scrollBox">
<table
class="tab-scroll"
ref="scroll"
@mouseenter="activeEve(false)"
@mouseleave="activeEve(true)"
>
<tbody>
<tr v-for="(si,idx) in deviceInfoList" :key="idx">
<td class="name">{{si.name || '-'}}</td>
<td class="type">{{si.type || '-'}}</td>
<td class="code">
<a
@click="handleClick(si)"
:class="{'isDisabled':(si.name !== '混凝土天花打磨') || si.sysState !== '3'}"
>{{si.deviceCode || '-'}}</a>
</td>
<td class="pos">{{si.posistion || '-'}}</td>
<td class="pos" v-if="si.sysState == '3'">{{Number(si.delayedTime)+'ms'}}</td>
<td class="pos" v-else>{{si.delayedTime || '-'}}</td>
<td
class="sysState"
:class="{'yellow': si.sysState == '2', 'green': si.sysState == '3'}"
>{{deviceStateArr[si.sysState] || '-'}}</td>
<td v-if="si.sysState == '3'">
<el-progress :percentage="si.progress || 0"></el-progress>
</td>
<td v-else>{{si.progress || '-'}}</td>
<td>{{si.workStartTime || '-'}}</td>
<td>{{si.workEndTime || '-'}}</td>
<td>{{si.duration}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="page-bar">
<el-pagination
background
layout="prev,pager, next"
:current-page="page"
:page-size="pageSize"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</div>
</div>
</template>
CSS
<style scoped lang='scss'>
table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
}
th,
td {
line-height: 35px;
color: #ffffff;
text-align: center;
word-break: keep-all; /* 不换行 */
white-space: nowrap; /* 不换行 */
overflow: hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow: ellipsis; /* for IE */
}
.scroll-box {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
.tab-scroll {
table-layout: fixed;
font-size: 16px;
position: absolute;
left: 0;
top: 0;
border-top: none;
padding-left: 60px;
.isDisabled {
pointer-events: none;
cursor: not-allowed;
}
.yellow {
color: #dada09;
}
.green {
color: #04ba19;
}
}
.left-button {
position: absolute;
left: 4px;
padding: 24px 14px;
top: 50%;
transform: translate(0, -50%);
width: 46px;
height: 221px;
color: #fff;
text-align: center;
line-height: 26px;
font-size: 18px;
z-index: 100;
border: solid 1px #31467d;
border-left: none;
color: #65c6e7;
}
.show {
background: url('../../../assets/dashboard/icon_packup.png');
width: 12px;
height: 14px;
transform: rotate(180deg);
display: inline-block;
background-size: contain;
}
.hide {
background: url('../../../assets/dashboard/icon_packup.png');
width: 12px;
height: 14px;
display: inline-block;
background-size: contain;
}
.deviceInfoBox {
table-layout: fixed;
font-size: 16px;
color: #fff;
width: 100%;
z-index: 50;
text-align: center;
transition: 500ms all ease-in;
th {
color: #65c6e7;
white-space: nowrap;
}
td {
color: #ffffff;
white-space: nowrap;
}
.yellow {
color: #dada09;
}
.green {
color: #04ba19;
}
}
.flex-row-center {
display: flex;
flex-direction: row;
align-items: center;
}
.flex-row {
display: flex;
flex-direction: row;
}
.flex-col-center {
display: flex;
flex-direction: column;
justify-content: center;
}
.network-container {
height: 100%;
overflow: auto;
min-width: 38.4rem;
background: url('./imgs/img_bg.png') no-repeat;
background-size: 100% 100%;
font-size: 50px;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
> div {
width: 100%;
}
.network-center {
position: relative;
margin: 0.2rem 0.4rem 0 0.4rem;
width: calc(100% - 0.8rem);
min-height: 9.64rem;
flex: 1;
overflow: hidden;
&:before {
content: '';
display: block;
height: 0.5rem;
width: 0.5rem;
position: absolute;
background: url('./imgs/img_map_bg_01.png') no-repeat;
background-size: 100% 100%;
left: 3px;
top: 3px;
z-index: 99;
}
img {
position: absolute;
background-size: 100% 100%;
height: 0.5rem;
width: 0.5rem;
z-index: 99;
}
> img:nth-child(1) {
right: 3px;
top: 3px;
}
> img:nth-child(2) {
right: 3px;
bottom: 2px;
}
&:after {
content: '';
height: 0.5rem;
width: 0.5rem;
position: absolute;
background: url('./imgs/img_map_bg_03.png') no-repeat;
background-size: 100% 100%;
bottom: 2px;
left: 3px;
z-index: 99;
}
.network-center-content {
border: solid 0.02rem #31467d;
width: calc(100% - 0.12rem);
height: 100%;
margin: 0.06rem;
overflow: hidden;
padding-left: 60px;
}
.page-bar {
position: absolute;
right: 0;
bottom: 0;
margin-right: 10px;
margin-bottom: 10px;
/deep/.el-pagination.is-background .btn-prev,
/deep/.el-pagination.is-background .btn-next,
/deep/.el-pagination.is-background .el-pager li {
background-color: #04162a;
border: solid 1px #31467d;
color: #2bfaff;
margin: 0 3px;
}
/deep/.el-pagination.is-background .el-pager li:not(.disabled).active {
background-color: #43d5d7;
}
}
}
}
</style>
JS
table轮询的方法:
methods: {
activeEve(val) {
this.scroll = val
const self = this,
wrapH = this.$refs.scrollBox.clientHeight,
sel = this.$refs.scroll,
tbody = sel.children[0],
tbodyH = tbody.clientHeight
let timer_s = null,
step = 0
if (this.scroll && tbodyH > wrapH) {
if (self.timer) clearTimeout(self.timer)
cycle()
} else {
if (self.timer) clearTimeout(self.timer)
}
function cycle() {
if (self.timer) clearTimeout(self.timer)
self.timer = setTimeout(function() {
scroll()
}, 2000)
}
function scroll() {
cancelAnimationFrame(timer_s)
timer_s = requestAnimationFrame(function fn() {
if (!tbody.children || !tbody.children.length) return
const trH = tbody.children[0].clientHeight
if (Math.abs(step) > trH) {
cancelAnimationFrame(timer_s)
step = 0
sel.style.marginTop = 0
tbody.appendChild(tbody.firstChild)
cycle()
} else {
step--
sel.style.marginTop = `${step}px`
timer_s = requestAnimationFrame(fn)
}
})
}
}
}
至此,table轮询功能已经实现。
过了一段时间,老大又说先不用轮询,用滚动条代替。
css修改默认滚动条样式
在原来的基础上,只需要一点小改动就可以实现,下面是css实现:
css
.scroll-box {
width: 100%;
height: 510px;
overflow: hidden;
overflow-y: scroll;
position: relative;
// 修改默认滚动条样式
// 修改默认滚动条样式
&::-webkit-scrollbar {/*滚动条整体样式*/
width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
height: 6px;
background: transparent;
}
&::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
background: transparent;
border-radius: 4px;
}
&:hover::-webkit-scrollbar-thumb {
background: hsla(0, 0%, 53%, 0.4);
}
&:hover::-webkit-scrollbar-track {/*滚动条里面轨道*/
background: hsla(0, 0%, 53%, 0.1);
}
// 如果需要轮询table,请注释掉上面的,放开下面的
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
好了,这样就可以了,鼠标移入的时候会出现,下面是效果:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。