记录一些需求开发中的小代码,如果以后有类似的功能需求,可快速复用。
调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import BroadcastQueue from './BroadcastQueue';
this.broadcastQueue = new BroadcastQueue((data) => { this.showHighlightTip(data); });
showHighlightTip(queueItem) { ... },
this.broadcastQueue.push({ tip, showBtn: false, order: 3, });
this.broadcastQueue.clear()
|
BroadcastQueue.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
export default class BroadcastQueue { constructor(onData) { this.onData = onData; this.queue = []; this.isRun = false; }
push(data) { console.log('BroadcastQueue().push', JSON.stringify(data)); if (data.order == null) { data.order = 100; }
if (this.queue.length === 0) { this.queue.push(data); } else { for (let i = 0; i < this.queue.length; i += 1) { const item = this.queue[i]; if (data.order < item.order) { this.queue.splice(i, 0, data); break; } else if (i === this.queue.length - 1) { this.queue.push(data); break; } } }
this.run(); }
run() { if (this.isRun) { return; } this.isRun = true; this.next(); }
next() { if (this.queue.length === 0) { this.isRun = false; return; }
const data = this.queue.shift(); this.onData(data); setTimeout(() => { this.next(); }, 10000); }
clear() { this.queue = this.queue.filter(item => item.order === 1); this.isRun = false; } }
|
其余部分代码:
因为广播展示区域高度是固定28px, 所以当内容高度大于容器高度时,需要一个滚动动画。
smartMarquee.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <template> <div class="smart-marquee" :style="{height: `${height}px`}"> <div ref="content"> <slot></slot> </div> </div> </template>
<script> export default { props: ['height'],
data() { return { diffH: 0, offset: 0, }; },
mounted() { this.initScroll(); },
methods: { initScroll() { this.diffH = this.$refs.content.clientHeight - this.height; console.log('diff', this.diffH, 'contentH', this.$refs.content.clientHeight); if (this.diffH <= 10) { return; }
setTimeout(() => { this.scroll(); }, 500); },
scroll() { window.requestAnimationFrame(() => { if (this.offset < this.diffH) { this.offset += 0.2; this.$refs.content.style.transform = `translateY(-${this.offset}px)`; this.scroll(); } else { setTimeout(() => { this.offset = 0; this.$refs.content.style.transform = 'translateY(0)'; this.scroll(); }, 500); } }); }, }, }; </script>
<style lang="scss" scoped> .smart-marquee { position: relative; overflow: hidden; .name { max-width: 71px; display: inline-block; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; vertical-align: middle; margin-top: -3px; } } </style>
|
1 2 3 4 5 6
| <smart-marquee :height="28"> <span v-for="(item, index) in data.tips.content.text" :key="index" :style="{color: item.color, fontSize: item.size + 'px'}" >{{utils.base64_utf8_decode(item.text)}}</span> </smart-marquee>
|