效果如圖

代碼
<template>
<div id="mar">
<!--主div分三部分,圖標,系統公告名字,展示區域-->
<div class="header">
<!--圖標-->
<img src="">
<!--名字-->
<span class="announcement">系統公告:</span> </div>
<!--公告展示塊-->
<div class="PackagingShell" id="PackagingShell">
<!--主題內容,展示內容區域-->
<div id="viewBox">
<!--文本主體-->
<span id="marquee">{{text}}</span>
<!--文本副本,實現無縫滾動-->
<span id="transcript" ></span>
</div>
<!--隱藏塊,用於獲取展示文本寬度-->
<div id="hide">{{text}}</div>
</div>
<div id="table">
<div id="scroll-box">
<div class="box" v-for="(i, index) in Arr" :key="index">
<span>{{i.text}}</span> <span>{{i.ssss}}</span> <span>{{i.right}}</span>
</div>
<div class="copy">
<div class=" box" v-for="(i, index) in copyArr" :key="index">
<span>{{i.text}}</span> <span>{{i.ssss}}</span> <span>{{i.right}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Marquee',
data () {
return {
text: '', // 內容
textWidth: 0, // 字符長度
isScroll: false, // 是否滾動
copyArr: [],
Arr: [...new Array(10).fill({text: '測無', ssss: '動無', right: '用於獲'}).map((i, index) => {return { text: '測無' + index, ssss: '動無', right: '用於獲'}})]
}
},
methods: {
init () { // 初始化函數
// this.text = response.body.data[0].messageContent
// 滾動內容賦值
this.text = '滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試滾動無縫鏈接測試'
},
// 橫向滾動
move () {
// 首先獲取整個內容的寬度,(展示內容會超出隱藏,無法通過獲取盒子寬度取到實際的內容寬度)
// 所以專門造了一個 div 塊來放內容,隱藏起來 (無法用根據字體內容來計算寬度的方法,存在誤差,當內容較多
// 的時候誤差會相對較大)
let width = document.getElementById('hide').getBoundingClientRect().width
// 獲取展示塊盒模型寬度
let BoxWidth = document.getElementById('PackagingShell').offsetWidth
// 獲取內容展示寬
let viewBox = document.getElementById('viewBox')
// 判斷內容是否超長
if ((BoxWidth - width) < 0) {
// 內容超長,則獲取抄本元素
let transcript = document.getElementById('transcript')
// 抄本元素內容填充
transcript.innerText = this.text
// 設定抄本和主題之間的間距
transcript.style.marginLeft = '200px'
} else {
// 沒有超長則return,不做任何操作
return
}
// 設置初始位移距離
let distance = 0
// 移動函數,通過定時器實現
setInterval(function () {
// 位移內用記錄是是遞減,此處的 1 控制移動變量 s
distance = distance - 1
// 判斷是否整個內容移動完
if (-distance >= width) {
// 若移動完,則重新設定位移值,此處賦值200是正好把 上面設置的塊間距 200px 也加入移動范圍,實現移動完無縫跳轉
distance = 200
}
// 實時設置位移距離
viewBox.style.transform = 'translateX(' + distance + 'px)'
}, 27) // 移動時間間隔t s和t 共同決定移動速度
},
// 豎向滾動
initTable() {
const table = document.getElementById('table')
const scrollBox = document.getElementById('scroll-box')
const scrollHeight = scrollBox.offsetHeight
const height = document.getElementById('scroll-box').scrollHeight
const copy = document.getElementsByClassName('copy')[0]
if (scrollHeight < table.offsetHeight) {
return
} else {
this.copyArr = this.Arr
copy.style.marginTop = '200px'
}
let distance = 0
setInterval(function () {
// 位移內用記錄是是遞減,此處的 1 控制移動變量 s
distance -= 1
// 判斷是否整個內容移動完
if (-distance >= scrollBox.offsetHeight) {
// 若移動完,則重新設定位移值,此處賦值table.offsetHeight是正好把 上面設置的塊間距 table.offsetHeight 也加入移動范圍,實現移動完無縫跳轉
distance = table.offsetHeight
}
// 實時設置位移距離
// scrollBox.scrollTop = distance
scrollBox.style.transform = 'translateY(' + distance + 'px)'
}, 16) // 移動
}
},
mounted () {
// 初始化
this.init()
this.initTable()
},
// 更新的時候運動
updated: function () {
this.move()
}
}
</script>
<style scoped >
#mar {
height:40px;
line-height: 40px;
}
/*系統公告字體顏色*/
.announcement{
color:#ff4786;
}
/*公告滾動盒子樣式*/
.PackagingShell {
width: 89%; /*滾動部分寬度*/
overflow: hidden; /*超出部分隱藏*/
font-size: 12px;
color: #111;
}
/*主題內容塊設置*/
#viewBox {
/*設置內容框不可換行,確保兩個div塊始終在同一行*/
white-space: nowrap;
}
/*內容塊設置*/
#marquee {
/*設置內容塊不可換行*/
white-space: nowrap;
}
/*獲取寬度的塊,用z-index隱藏*/
#hide {
position: absolute;
z-index: -999;
top: -9999px;
white-space: nowrap;
}
/*浮動設置和圖片設置*/
.header {
float: left;
font-size:12px;
}
#table {
width: 100%;
height: 300px;
overflow: hidden;
}
#table .box {
height: 35px;
display: flex;
justify-content: space-around;
}
#table #scroll-box {
/* width: 100%; */
/* height: 300px; */
/* overflow-y: auto; */
}
</style>
