当前位置: 首页 > Web前端 > HTML5

原生table实现轮询+css修改默认滚动条样式

时间:2023-04-05 17:13:22 HTML5

最近做项目(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>JStable轮询的方法: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;}好了,这样就可以了,鼠标移入的时候会出现,下面是效果: