vue 实现设定规定个数列表滚动
2019-10-31 本文已影响0人
Coldhands
<template>
<div class="hot_news">
<div class="news_list">
<ul class="news_list_top">
<li>新闻类别</li>
<li>新闻标题</li>
<li>新闻时间</li>
</ul>
<div class="scroll_container">
<ul class="hot_news_scroll" id="hotNewsScroll">
<li v-for="(item, index) in hotNews" :key="index">
<p>【{{item.newsClassesEntity.classes}}】</p>
<el-tooltip :content="item.title" placement="bottom" effect="light">
<p>{{item.title}}</p>
</el-tooltip>
<p>{{item.publishTime ? item.publishTime.split(" ")[0] : ""}}</p>
<i class="hot-tip iconfont icon-hot" v-if="[0,1].includes(index)"></i>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
hotNews: {
type: Array,
default: () => {
return [];
}
}
},
data() {
return {
oList: null,
scrollTimer: null,
speed: null,
scrollNum: null,
TagName: null,
distance: null
};
},
mounted() {
this.initScroll("hotNewsScroll", "li", 1, 2000);
},
methods: {
initScroll(listId, TagName, scrollNum, speed) {
this.oList = this.$$Dom(listId);
this.scrollTimer = null;
this.speed = speed || 1000;
this.scrollNum = scrollNum || 0;
this.TagName = TagName;
this.distance =
this.oList.getElementsByTagName(TagName)[0].offsetHeight *
this.scrollNum; //列表移动距离
this.oList.style.marginTop = 0 + "px";
this.oList.onmouseover = () => {
this.pauseScroll();
};
this.oList.onmouseout = () => {
this.scrollTimer = setTimeout(() => {
this.playScroll();
}, this.speed);
};
this.playScroll();
},
playScroll() {
let options = { marginTop: "-" + this.distance };
this.animScroll(this.oList, options, () => {
//回调函数,移动列表元素
for (let i = 0, j = 0; i < this.scrollNum; i++) {
var node = this.oList.getElementsByTagName(this.TagName)[j];
if (this.TagName == "tr") {
this.oList.getElementsByTagName("tbody")[0].appendChild(node);
} else {
this.oList.appendChild(node);
}
}
this.oList.style.marginTop = "0px";
});
this.scrollTimer = setTimeout(() => {
this.playScroll(this.distance);
}, this.speed);
},
pauseScroll() {
clearTimeout(this.scrollTimer);
},
animScroll(oElement, oAttr, fnCallback) {
var _this = this;
clearInterval(oElement.timer);
oElement.timer = setInterval(() => {
let bStop = true;
for (let property in oAttr) {
let iCur = parseFloat(this.cssScroll(oElement, property)); //获取当前位置属性值
let iSpeed = (oAttr[property] - iCur) / 5; //移动进度
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if (iCur != oAttr[property]) {
//如果当前数值不等于目标数值,则数值递增
bStop = false;
this.cssScroll(oElement, property, iCur + iSpeed);
}
}
if (bStop) {
clearInterval(oElement.timer);
fnCallback && fnCallback.apply(_this, arguments);
}
}, 50);
},
cssScroll(oElement, attr, value) {
if (arguments.length == 2) {
return oElement.currentStyle
? oElement.currentStyle[attr]
: getComputedStyle(oElement, null)[attr];
} else if (arguments.length == 3) {
switch (attr) {
case "top":
case "left":
case "marginTop":
oElement.style[attr] = value + "px";
break;
default:
oElement.style[attr] = value;
break;
}
}
},
$$Dom(o) {
if (o) {
return document.getElementById(o);
}
}
}
};
</script>
<style lang="scss">
.hot_news {
height: 100%;
.news_list {
height: 100%;
box-sizing: border-box;
padding: 50px 20px 10px;
.news_list_top {
height: 26px;
line-height: 26px;
font-size: 12px;
background: rgba(80, 180, 255, 0.05);
li {
float: left;
width: 20%;
color: #d3f5ff;
box-sizing: border-box;
padding: 0 6px;
&:nth-of-type(2) {
width: 60%;
}
}
}
.scroll_container {
width: 100%;
max-height: 168px;
height: 88%;
overflow: hidden;
li {
height: 28px;
line-height: 28px;
border-bottom: 1px dashed rgba(67, 237, 248, 0.25);
cursor: pointer;
position: relative;
.hot-tip {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: #c11922;
font-size: 24px;
}
p {
float: left;
width: 20%;
margin: 0;
height: 100%;
line-height: 28px;
font-size: 13px;
color: #d3f5ff;
&:nth-of-type(2) {
width: 60%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
box-sizing: border-box;
padding-right: 20px;
}
}
}
}
}
}
</style>