vue 开发间隔式自动滚动组件
项目需求千奇百怪,只能尽其所能实现一二。
因开发vue前端,故此次使用vue开发一个间隔式自动滚动组件,代码如下
<template> <div id="autoScrll"></div> </template> <script> export default { name: 'autoScroll', props: { ele: HTMLDivElement,// 滚动容器dom元素 必填 step: { // 步进值 正数 非必填 默认 10 type: Number, default: 10 }, interval: { // 距下一次滚动时间间隔 单位ms 非必填 默认1000ms type: Number, default: 1000 }, mode: { // 滚动模式 1:按步进值(step)跳跃式滚动, 2:按照步进值(step)动画方式滚动 type: Number, default: 1 }, speed: { // 模式2 下可设置滚动速度 type: Number, default: 25 } }, data() { return { scrollStep: 0, // 由于props中的值不能直接修改,在data中再声明一个变量,用于动态的修改步进值 stopScrollTopFlag: false, stTimeout: undefined, stInterval: undefined, slTimeout: undefined, slInterval: undefined } }, methods: { autoScrollTop() { if (this.ele) { if (!this.scrollStep) { if (!this.step || isNaN(this.step)) this.scrollStep = 10; else this.scrollStep = this.step } if (!this.interval || isNaN(this.interval)) this.interval = 1000; if (this.scrollStep < 10 || !this.mode) mode = 1; const hh = this.ele.offsetHeight; const hh2 = this.ele.scrollHeight; if (hh2 > hh) { let i = 0; let ss = 0; let scroll = this.ele.scrollTop; if (scroll <= 0 || scroll >= (hh2 - hh)) { scroll = 0; } else { i = (scroll / this.scrollStep ) + (scroll % this.scrollStep == 0 ? 0 : 1); if ((this.scrollStep * i) >= (hh2 - hh)) { if (scroll % this.scrollStep == 0) { i = 0; scroll = 0; } else { ss = (this.scrollStep * i) - scroll; scroll = this.scrollStep * i; } } } if (this.mode == 1) { // 开始滚动 每次步进滚动一个step高度 this.stInterval = setInterval(() => { this.ele.scrollTop = scroll; if ((hh + scroll) >= hh2) { scroll = 0; } else { scroll += this.scrollStep ; } }, this.interval); } else if (this.mode == 2) { this.scrollToTop(hh, hh2, i, scroll - ss); } } } }, scrollToTop(hh, hh2, i, scroll) { let interval2 = setInterval(() => { if (!this.stopScrollTopFlag) { this.ele.scrollTop = scroll; if ((hh + scroll) >= hh2) { i = 0; scroll = 0; clearInterval(interval2); this.stTimeout = setTimeout(() => { if (!this.stopScrollTopFlag) { this.scrollToTop(hh, hh2, i, scroll); this.stopScrollTop(); } else { this.stopScrollTop(); } }, this.interval); } else if (scroll >= (this.scrollStep * i)) { i++; clearInterval(interval2); this.stTimeout = setTimeout(() => { if (!this.stopScrollTopFlag) { this.scrollToTop(hh, hh2, i, scroll); this.stopScrollTop(); } else { this.stopScrollTop(); } }, this.interval); } else { scroll += 2; } } else { clearInterval(interval2); } }, this.speed); }, stopScrollTop () { if (this.stTimeout) { clearTimeout(this.stTimeout); this.stTimeout = undefined; } if (this.stInterval) { clearInterval(this.stInterval); this.stInterval = undefined; } } } } </script>
这里在之前写好的table表格组件中引用,实现表格的自动滚动效果,代码如下:
<template> <div> <div class="table-head"> <table class="layui-table" style=""> <colgroup> <col v-for="(colItem, idx) in cols" :key="'col-' + idx" :style="{width: getColWidth(colItem)}"/> </colgroup> <thead> <tr> <th v-for="(colItem, idx2) in cols" :key="'th-' + idx2" :style="{textAlign: getAlign(colItem)}" >{{ colItem.title }}</th> </tr> </thead> </table> </div> <div ref="dataTableBox" class="table-body" :style="{height: getHeight()}"> <!-- 重点:使用引入的autoScroll组件 --> <!-- $refs.dataTableBox 为监听的滚动的容器 dataTableBox 为容器 ref属性对应的值 --> <auto-scroll ref="autoScroll" :ele="$refs.dataTableBox" :step="0" :interval="1500" :mode="2" /> <table ref="dataTable" class="layui-table" style="background: #0001271a;"> <colgroup> <col v-for="(colItem, idx3) in cols" :key="'col2-' + idx3" :style="{width: getColWidth(colItem)}"/> </colgroup> <!-- <tbody ref="dataTableBody" v-if="data && data.length > 0" @mouseover="stopScroll" @mouseleave="startToScroll"> --> <!-- 重点:鼠标移入或移动时停止滚动,鼠标移除时继续开始滚动 --> <tbody ref="dataTableBody" v-if="data && data.length > 0" @mousemove="stopScroll2" @mouseover="stopScroll2" @mouseleave="startToScroll2"> <tr v-for="(dtItem, idx5) in data" :key="'dt-' + idx5" :class="[idx5%2 == 1 ? 'color1' : '']"> <td v-for="(colItem, idx6) in cols" :key="'col3-' + idx6" :style="{textAlign: getAlign(colItem)}"> <div v-if="colItem.type && colItem.type == 'num'">{{ idx5 + 1 }}</div> <div v-else>{{ dtItem[colItem.field] }}</div> </td> </tr> </tbody> <tbody v-else> <tr class="color1"> <td :colspan="cols.length" style="text-align: center;">暂无数据</td> </tr> </tbody> </table> </div> <div :class="[isShow==5?'load_more':'load_more1']" v-if="isload"> <div @click="loadMore()">加载更多<img src="../assets/images/loadMore.png" alt=""></div> </div> </div> </template> <script> import autoScroll from './autoScroll.vue' export default { name: 'tablePy', components: {autoScroll}, props: { "cols": { type: Array, default: [ {type: "num", title: '序号'}, {field: "field1", title: '字段1'}, {type: "field2", title: '字段2'}, ] }, "data": { type: Array, default: [] }, "isload": { type: Boolean, default: false }, "height": { type: String|Number, default: 190 } }, data() { return { datas: [], // autoScroll: autoScroll, scrollInterval: undefined } }, watch: { data() { // 重点:监听到表格数据变化时,等待数据表格渲染完成,再开始渲染自动滚动 // this.$refs.autoScroll.scrollStep 动态的修改间歇式滚动的步进值 this.$nextTick(() => { // this.ele = this.$refs.dataTableBox; this.$refs.autoScroll.scrollStep = this.$refs.dataTableBody.firstElementChild.offsetHeight; this.startToScroll2(); }); } }, methods: { loadMore() { this.$emit('loadMore'); return false; }, getTitle(colItem) { const title = colItem.title; if (title) { return title; } else { if (colItem.type && colItem.type == 'num') { return '序号'; } else { return colItem.field; } } }, getColWidth(colItem) { const type = colItem.type; const width = colItem.width; if (width) { if ((width + '').slice(-1) == '%' || (width + '').slice(-2) == 'px') { return width; } else { return width + 'px'; } } else { if (type && 'num' == type) { return 80 + 'px'; } else { return 'auto'; } } }, getAlign(colItem) { const align = colItem.align; if (align && ('center' == align || 'left' == align || 'right' == align)) { return align; } else { return left; } }, getHeight() { if ((this.height + '').slice(-1) == '%' || (this.height + '').slice(-2) == 'px') { return this.height; } else { if (Number(this.height) < 90) { return '90px'; } else { return this.height + 'px'; } } }, stopScroll2() { // 修改子组件变量值,调用子组件停止滚动方法 this.$refs.autoScroll.stopScrollTopFlag = true; this.$refs.autoScroll.stopScrollTop(); }, startToScroll2() { // 调用子组件开始滚动方法 this.$refs.autoScroll.stopScrollTopFlag = false; this.$refs.autoScroll.autoScrollTop(); } }, mounted() { // 通过$once来监听定时器,在beforeDestroy钩子可以被清除。 this.$once('hook:beforeDestroy', () => { this.stopScroll2(); }); } }; </script> <style lang="less" scoped> .table-body { width: 100%; overflow-y: auto; } .table-body::-webkit-scrollbar { width: 0; } table.layui-table { margin: 0; width: 100%; color: #ffffff; background: rgba(14, 43, 117, 0.3); thead { tr { background: rgba(14, 43, 117, 0.3); } } // tr { // width: 100%; // display: flex; // overflow: hidden; // background: rgba(14, 43, 117, 0.5); // } th, td { border: none; font-size: 16px; padding: 9px 3px; } .color1 { background: #07164e88; } tbody tr:hover { background: rgba(14, 43, 117, 0.6); } } .load_more { margin-top: 0.4rem; width: 110%; height: 0.45rem; border: 0.01rem solid #32c5ff; font-size: 0.16rem; line-height: 0.45rem; text-align: center; cursor: pointer; margin-bottom: 0.5rem; color: #32c5ff; img { width: 0.2rem; height: 0.12rem; } } .load_more1 { margin-top: 0.4rem; width: 100%; height: 0.45rem; border: 0.01rem solid #32c5ff; font-size: 0.16rem; line-height: 0.45rem; text-align: center; cursor: pointer; margin-bottom: 0.5rem; color: #32c5ff; img { width: 0.2rem; height: 0.12rem; } } </style>
代码比较多,第二段中相应的引用和使用方法已做 注明。
目前只写了纵向滚动的,等有时间再补充横向滚动的相关效果