这个跑马灯的实现思路其实跟轮播无缝连接的思路是一样的。实现的效果如下(这个软件的水印真的好明显,小小字在跑的就是跑马灯了=.=):
跑马灯的样式和html
<div class="notice-container">
<span class="notice-icon"></span>
<div class="notice-items" ref="noticeBox">
<div class="notice-items-inner" ref="noticeInner">
<p>1、这是第一条跑马灯!!!!!!!!!</p>
<p>2、这是第二条跑马灯!!!</p>
<p>3、这是第三条跑马灯!!!</p>
<p>1、这是第一条跑马灯!!!!!!!!!</p> <!-- 这里是复制第一条数据,以做到无缝衔接 -->
</div>
</div>
</div>
样式定义如下
.notice-container {
margin-top: 10px;
background: #FFFFFF;
font-size: 12px;
color: #3E4759;
height: 30px;
overflow: hidden;
box-sizing: border-box;
width: 100%;
display: flex;
align-items: center;
.notice-icon {
display: block;
margin-left: 10px;
flex-shrink: 0;
width: 27px;
height: 27px;
background: url("../assets/home/icon_home_gg.png") no-repeat;
background-size: 100% 100%;
}
.notice-items {
margin: 0 0 0 6px;
flex: 1;
display: flex;
overflow: hidden;
.notice-items-inner {
display: flex;
width: 100%;
p {
flex-shrink: 0; // 这个结合父级的flex,可以做到不换行
margin-right: 100%; // 这里的需求是一行切换完之后才能看到下一行的需求,所以加了100%的margin
white-space: nowrap;
}
}
}
}
js处理如下:
initHorseLamp () {
let boxWidth = this.$refs.noticeBox.offsetWidth // 这个盒子的宽度
let innerWidth = 0
let child = this.$refs.noticeInner.childNodes
child.forEach(item => {
innerWidth += item.offsetWidth
})
innerWidth += boxWidth * (child.length - 1) // 这里计算的是内容的宽度
if (innerWidth > boxWidth) {
let padding = 0
let animation = () => {
padding -= 1
this.$refs.noticeInner.style.cssText = `transform: translate3d(${padding}px, 0, 0)`
if (padding === -(innerWidth - child[0].offsetWidth)) { // 当刚好移到倒数第一条时,将padding置为0,就可以衔接上了,这也是将第一条复制到最后一条的原因
padding = 0
this.$refs.noticeInner.style.cssText = `transform: translate3d(${padding}px, 0, 0)`
}
requestAnimationFrame(animation) // 每16毫秒移动1像素
}
animation()
}