封装成了Vue控件,可直接传入数据使用,根据需求少量修改即可。
两个点:
1:对于不需要根据位置来控制轮播过程中的显示的需求,可使用transform来做(提升至合成层),帧率等效果会更好; 对于一些需要控制速度且需要配合位置的需求, 可采用定时器加window.requestAnimationFrame递归来做。(对于优化方面,可参考https://zhuanlan.zhihu.com/p/30078937)
2:消息轮播和整页的图片轮播不太一样,图片轮播可采取首位各增加一张图片来达到头尾循环轮播,而这种消息轮播基本直接是二倍dom移动。而对于实时无限消息轮播就又不一样,这种可控制单条消息div的移动来实现轮播,复用时更新消息内容。

<template>
<div id="dome">
<div id="dome1">
<div class="a" v-for="(item, index) in newsList" :key="index">
<div class='lilicontent'>
<img class="itemImg" :src="item.headImage" alt="">
<div class="itemName">{{ handNikeName(item.nickname ) }}</div>
<div class="itemContend">{{ item.desc }}</div>
</div>
</div>
</div>
<div id="dome2"></div>
</div>
</template>
<style scoped>
#dome{
overflow:hidden; /*溢出属性*/
margin-left: 0px;
margin-top: 0px;
padding-left: 20px;
}
.a{
padding: 5px 0px 5px 0px;
}
.item{
color: red;
background-color: greenyellow;
border-radius: 15px;
text-align: center;
height: 30px;
line-height: 30px;
/* width: 100%; */
}
.lilicontent{
background-color: rgba(255, 197, 116, 1);
display: flex;
color: rgba(51, 51, 51, 1);
font-size: 12px;
border-radius: 16px;
}
.itemImg{
display: inline-block;
width: 20px;
height: 20px;
background-color: red;
border-radius: 11px;
margin-left: 5px;
margin-top: 3.5px;
flex-shrink: 0;
}
.itemName{
display: inline-block;
line-height: 28px;
height: 28px;
padding-left: 7px;
padding-right: 7px;
flex-shrink: 0;
}
.itemContend{
display: inline-block;
line-height: 28px;
padding-right: 7px;
flex-shrink: 0;
}
</style>
<script>
import scroll from 'vue-seamless-scroll'
export default {
components:{
scroll,
},
props:{
newsList:{
type:Array,
default: () => {
return [];
}
},
},
data () {
return {
dome:'', //控制滚动的dom
dome1:'',
dome2:'',
timer: '', //定时器变量
viewHeight: 120, //控件高度
viewWidth: 230, //控件宽度
}
},
mounted() {
this.donghua()
},
destroyed() {
window.clearInterval(this.timer);
},
methods: {
// 处理昵称
handNikeName(nikename){
if(nikename && nikename.length>4){
let nikeArr = Array.from(nikename);
nikename = nikeArr.slice(0, 2).join('') + '**' + nikeArr[nikeArr.length-1];
return nikename
}
else{
return nikename
}
},
// 轮播动画
donghua(){
//获取三个<div>对象
this.dome = document.getElementById("dome");
this.dome.style = 'height:'+this.viewHeight+'px;'+'width:'+this.viewWidth+'px;';
this.dome1 = document.getElementById("dome1");
this.dome2 = document.getElementById("dome2");
//将dome1的内容,复制到dome2中
this.dome2.innerHTML = this.dome1.innerHTML;
//定时器
this.timer = setInterval(()=>{
window.requestAnimationFrame(this.start) //使用此函数解决卡顿问题
},16);
},
// 开始滚动
start(){
//如果滚动上去的距离,等于或大于dome1的高度,则复位开始下一次滚动
if(this.dome.scrollTop >= this.dome1.offsetHeight)
{
this.dome.scrollTop = 0;
}else
{
this.dome.scrollTop =this.dome.scrollTop + 1;
}
this.jisuanOpcity()
},
// 透明度计算
jisuanOpcity(){
let tioaji = 20; //调剂变量,用来使头部透明度更低
let hh = document.getElementsByClassName('a')[0].offsetHeight;
for(let i=0; i<this.newsList.length*2; i++){
if(hh*(i+1)<this.dome.scrollTop){
document.getElementsByClassName('a')[i].style = 'opacity:'+0;
}else if((hh*(i+1) - this.dome.scrollTop - tioaji) > this.viewHeight){
document.getElementsByClassName('a')[i].style = 'opacity:'+1;
}else{
let opcityx = (hh*(i+1) - this.dome.scrollTop - tioaji) / this.viewHeight;
document.getElementsByClassName('a')[i].style = 'opacity:'+ opcityx;
}
}
},
},
}
</script>
网友评论