一次,要實現一個公告,需要走馬燈效果。
發現,文字的寬度計算是需要用一個模擬的元素來計算的,因為我們用來實現走馬燈效果的元素肯定是要設置overflow:hidden;
的。
即,我們不可能用走馬燈效果本身需要用到的div來計算文字的總寬度。
其次,也要注意各個端的font-size
,文字的寬度與此相關,是否跑馬燈也是相關的
案例效果如下:
Vue實現的代碼如下:
文字長度不夠一行則不跑馬燈。
<template>
<div class="wrap">
<div class="icon-wrap">
+
</div>
<div class="text-wrap" ref="textWrapDom">
<div class="text-content" ref="textContentDom">
{{text}}
</div>
</div>
<!-- 空的dom,不展示,僅用於計算文字的寬度 -->
<div class="virtual-dom" ref="virtualDom">
{{text}}
</div>
<div class="more">
更多
</div>
</div>
</template>
<script>
export default {
name: 'HomeNotice',
props: {
layout: {},
data: {},
},
computed: {
// 跑馬燈效果的文字
text() {
return '桃李春風一杯酒,江湖夜雨十年燈。西風吹老洞庭波,一夜湘君白發多。醉后不知天在水,滿船清夢壓星河。'
}
},
data () {
return {
timer: null,
}
},
mounted () {
setTimeout(() => {
this.move()
}, 1000)
},
beforeDestroy() {
clearInterval(this.timer)
this.timer = null
},
methods: {
move() {
// 可視區域的寬度
let curWidth = this.$refs.textWrapDom.offsetWidth
// 所有文字的寬度
let allWidth = this.$refs.virtualDom.offsetWidth
console.log(curWidth, allWidth)
// 位移距離
let distance = 0
if (allWidth > curWidth) {
this.timer = setInterval(() => {
distance = distance - 1
// 如果位移超過文字寬度,則回到起點
if (-distance >= (allWidth - 150)) {
distance = 40
}
if (this.$refs.textContentDom) {
this.$refs.textContentDom.style.transform = 'translateX(' + distance + 'px)'
}
}, 20)
}
},
}
}
</script>
<style scoped>
* {
margin: 0;
padding: 0;
list-style: none;
}
.wrap {
margin: 5px 14px;
height: 34px;
display: flex;
}
.icon-wrap {
display: flex;
height: 34px;
align-items: center;
margin-right: 10px;
flex: 0 0 20px;
font-size: 20px;
}
.text-wrap {
flex: 1;
overflow: hidden;
}
.text-content {
display: flex;
align-items: center;
height: 34px;
font-size: 14px;
font-weight: 300;
color: rgba(0, 0, 0, 0.55);
white-space: nowrap;
}
.more {
position: relative;
padding-left: 14px;
padding-right: 8px;
display: flex;
align-items: center;
height: 34px;
font-size: 12px;
font-weight: 400;
color: #4FA3FF;
box-shadow: -7px 0px 7px -7px rgba(59, 61, 68, 0.1);
}
.virtual-dom {
position:absolute;
visibility: hidden;
white-space: nowrap;
z-index: -100;
}
</style>
complete.