5 changed files with 226 additions and 117 deletions
-
46src/assets/styles/index.scss
-
225src/views/notice/index.vue
-
28src/views/readStar/index-height.vue
-
28src/views/readStar/index.vue
-
16src/views/video/index.vue
@ -1,73 +1,152 @@ |
|||
<template> |
|||
<!-- 通知公告 --> |
|||
<div class="screen-item notice"> |
|||
<div class="common-title">通知公告</div> |
|||
<div class="small-module module-content"> |
|||
<span class="notice-icon-gif" /> |
|||
<div class="seamless-warp"> |
|||
<div class="notice-txt" v-html="content" /> |
|||
</div> |
|||
<!-- <vue-seamless-scroll :data="noticeData" :class-option="defaultOption" class="seamless-warp"> |
|||
<p v-for="(item,index) in noticeData" :key="index"> {{ item.des }}</p> |
|||
</vue-seamless-scroll> --> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { FetchInitNotice } from '@/api/library' |
|||
export default { |
|||
name: 'Notice', |
|||
data() { |
|||
return { |
|||
noticeData: [], |
|||
content: '' |
|||
} |
|||
}, |
|||
computed: { |
|||
defaultOption() { |
|||
return { |
|||
step: 0.3, // 数值越大速度滚动越快 |
|||
limitMoveNum: 1, // 开始无缝滚动的数据量 |
|||
hoverStop: false, // 是否开启鼠标悬停stop |
|||
direction: 1, // 0向下 1向上 2向左 3向右 |
|||
openWatch: true // 开启数据实时监控刷新dom |
|||
} |
|||
} |
|||
}, |
|||
created() { |
|||
}, |
|||
mounted() { |
|||
this.getInitNotice() |
|||
}, |
|||
methods: { |
|||
// 处理方法 |
|||
escapeHtml(str) { |
|||
var arrEntities = { |
|||
'lt': '<', |
|||
'gt': '>', |
|||
'nbsp': ' ', |
|||
'amp': '&', |
|||
'quot': '"' |
|||
} |
|||
return str.replace(/&(lt|gt|nbsp|amp|quot|pre);/ig, function(all, t) { |
|||
return arrEntities[t] |
|||
}) |
|||
}, |
|||
getInitNotice() { |
|||
FetchInitNotice().then((res) => { |
|||
if (res.errCode === 0) { |
|||
this.content = this.escapeHtml(res.data) |
|||
} else { |
|||
this.$message.error('接口错误') |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import "~@/assets/styles/index.scss"; |
|||
|
|||
</style> |
|||
<template> |
|||
<!-- 通知公告 --> |
|||
<div class="screen-item notice"> |
|||
<div class="common-title">通知公告</div> |
|||
<div class="small-module module-content"> |
|||
<span class="notice-icon-gif" /> |
|||
|
|||
<!-- 核心:给容器加固定宽度,避免宽度溢出导致滚动失效 --> |
|||
<div ref="box" class="seamless-warp"> |
|||
<div ref="text" class="notice-txt" v-html="content" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { FetchInitNotice } from '@/api/library' |
|||
|
|||
export default { |
|||
name: 'Notice', |
|||
data() { |
|||
return { |
|||
content: '', |
|||
scrollTimer: null, // 滚动定时器 |
|||
transitionTimer: null, // 过渡结束定时器 |
|||
boxH: 0, // 容器高度 |
|||
textH: 0, // 内容高度 |
|||
duration: 40000 // 单次滚动时长 |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getInitNotice() |
|||
}, |
|||
beforeDestroy() { |
|||
// 销毁时清除所有定时器 |
|||
if (this.scrollTimer) clearInterval(this.scrollTimer) |
|||
if (this.transitionTimer) clearTimeout(this.transitionTimer) |
|||
}, |
|||
methods: { |
|||
escapeHtml(str) { |
|||
if (!str) return '' |
|||
var arrEntities = { |
|||
'lt': '<', |
|||
'gt': '>', |
|||
'nbsp': ' ', |
|||
'amp': '&', |
|||
'quot': '"' |
|||
} |
|||
return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, (all, t) => arrEntities[t]) |
|||
.replace(/<pre>|<\/pre>/gi, '') |
|||
.replace(/\\r\\n/g, '') // 移除多余换行符 |
|||
}, |
|||
getInitNotice() { |
|||
FetchInitNotice().then(res => { |
|||
if (res.errCode === 0) { |
|||
this.content = this.escapeHtml(res.data) |
|||
// 等DOM完全渲染后再启动滚动 |
|||
this.$nextTick(() => { |
|||
this.startScroll() |
|||
}) |
|||
} |
|||
}).catch(err => { |
|||
console.log('接口请求失败:', err) |
|||
}) |
|||
}, |
|||
startScroll() { |
|||
const box = this.$refs.box |
|||
const text = this.$refs.text |
|||
|
|||
// 先打印调试,看是否获取到DOM和高度 |
|||
console.log('容器DOM:', box) |
|||
console.log('内容DOM:', text) |
|||
if (!box || !text) { |
|||
console.log('DOM未获取到,滚动启动失败') |
|||
return |
|||
} |
|||
|
|||
// 强制计算高度(解决rem布局高度计算延迟) |
|||
this.boxH = box.clientHeight || parseInt(getComputedStyle(box).height) |
|||
this.textH = text.offsetHeight || parseInt(getComputedStyle(text).height) |
|||
|
|||
console.log('容器高度:', this.boxH, '内容高度:', this.textH) |
|||
|
|||
// 内容不够高,不滚动 |
|||
if (this.textH <= this.boxH) { |
|||
console.log('内容高度小于容器,无需滚动') |
|||
return |
|||
} |
|||
|
|||
// 初始化样式 |
|||
text.style.position = 'absolute' |
|||
text.style.top = '0px' |
|||
text.style.left = '0px' |
|||
text.style.width = '100%' |
|||
text.style.transition = 'none' |
|||
|
|||
// 监听过渡结束事件,实现循环 |
|||
text.addEventListener('transitionend', this.handleTransitionEnd) |
|||
|
|||
// 启动第一次滚动 |
|||
this.rollToBottom() |
|||
}, |
|||
// 滚动到底部 |
|||
rollToBottom() { |
|||
const text = this.$refs.text |
|||
// 重置过渡,立即回到顶部 |
|||
text.style.transition = 'none' |
|||
text.style.top = '0px' |
|||
|
|||
// 重新设置过渡,滚动到底部 |
|||
setTimeout(() => { |
|||
text.style.transition = `top ${this.duration}ms linear` |
|||
text.style.top = `-${this.textH - this.boxH}px` |
|||
}, 100) |
|||
}, |
|||
// 过渡结束处理函数 |
|||
handleTransitionEnd() { |
|||
// const text = this.$refs.text |
|||
// 清除之前的定时器,避免重复触发 |
|||
if (this.transitionTimer) clearTimeout(this.transitionTimer) |
|||
|
|||
// 停留2秒后重新滚动 |
|||
this.transitionTimer = setTimeout(() => { |
|||
this.rollToBottom() |
|||
}, 2000) // 2000毫秒 = 2秒 |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import "~@/assets/styles/index.scss"; |
|||
|
|||
.notice .module-content { |
|||
position: relative; |
|||
} |
|||
|
|||
.notice .seamless-warp { |
|||
position: relative !important; |
|||
overflow: hidden !important; |
|||
height: 3.1rem !important; |
|||
} |
|||
|
|||
.notice-txt table { |
|||
width: 100% !important; |
|||
border-collapse: collapse !important; |
|||
} |
|||
|
|||
.notice-txt td { |
|||
word-break: break-all !important; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue