先看效果图:
公告:可以有多条,长度短的直接向上轮播,长度长的先往左滚动,滚动完成后再向上轮播;
鼠标悬浮,公告上下停止滚动,内容超出宽度时,左右继续滚动;
代码:
<template>
<div class="notice">
<div class="notice_left">
<i class="el-icon-chat-line-round icon"></i>
<span>公告</span>
</div>
<div
class="notice_right"
@mouseover="flag = false"
@mouseleave="flag = true"
>
<el-carousel
height="0.8rem"
direction="vertical"
:autoplay="false"
indicator-position="none"
:initial-index="0"
ref="carousel"
>
<el-carousel-item v-for="(item, index) in gg" :key="index">
<div class="medium">{{ item.noticeContent }}</div>
</el-carousel-item>
</el-carousel>
</div>
<!-- <div class="notice_more">
<span>更多</span>
</div> -->
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
count: 0,
left: 0,
index: 0,
frameNum: 0,
flag: true,
// gg: [],
interval: null,
timeOut: null,
timeOut2: null,
doms: null,
inner: null,
};
},
props: {
gg: {
type: Array,
default: [],
},
},
watch: {
index: {
handler(val1, val2) {
if (this.flag) {
// this.scroll();
}
},
deep: true,
},
flag: {
handler(val1, val2) {
if (val1) {
window.cancelAnimationFrame(this.frameNum);
this.scroll();
}
},
deep: true,
},
gg: {
handler(val1, val2) {
if (val1 && val1.length > 0) {
this.scroll();
}
},
immediate: true,
deep: true,
},
},
mounted() {
window.addEventListener("resize", () => {
window.cancelAnimationFrame(this.frameNum);
this.scroll()
})
},
methods: {
setActiveItem(index) {
if (this.$refs.carousel) {
this.$refs.carousel.setActiveItem(index);
}
},
setIndex() {
if (this.index == this.gg.length - 1) {
this.index = 0;
} else {
this.index += 1;
}
},
setIntervalMth() {
if (this.doms) {
if (this.left >= this.count) {
this.count += 1;
this.inner[0].style.left = -this.count + "px";
this.frameNum = window.requestAnimationFrame(this.setIntervalMth);
// setTimeout(() => {
// this.setIntervalMth()
// },30)
} else {
this.count = 0;
this.inner[0].style.left = "0px";
clearTimeout(this.timeOut);
window.cancelAnimationFrame(this.frameNum);
if (this.flag) {
this.setIndex();
this.setActiveItem(this.index);
this.scroll();
} else {
this.scroll();
}
}
}
},
scroll() {
this.count = 0;
clearTimeout(this.timeOut);
clearTimeout(this.timeOut2);
this.$nextTick(() => {
this.doms = document.getElementsByClassName("is-active");
this.inner = this.doms[0].getElementsByClassName("medium");
if (
this.inner[0] &&
this.doms[0] &&
this.inner[0].scrollWidth > 0 &&
this.doms[0].offsetWidth > 0
) {
// 文字内容超出
if (this.inner[0].scrollWidth > this.doms[0].offsetWidth) {
this.left = this.inner[0].scrollWidth - this.doms[0].offsetWidth;
this.timeOut = setTimeout(() => {
this.count = 0;
this.setIntervalMth();
}, 2000);
} else {
// 文字内容未超出
this.timeOut2 = setTimeout(() => {
if (this.flag) {
this.setIndex();
this.setActiveItem(this.index);
this.scroll();
} else {
this.setActiveItem(this.index);
}
}, 2000);
}
}
});
},
},
};
</script>
<style lang="scss" scoped>
@function autoPx($num) {
@return (($num / 1200) * 24rem);
}
.notice {
display: flex;
align-items: center;
padding: 0 autoPx(10);
.notice_left {
display: flex;
align-items: center;
justify-content: center;
width: autoPx(60);
font-weight: 600;
height: autoPx(40);
line-height: autoPx(40);
.icon {
font-size: autoPx(15);
}
span {
font-size: autoPx(15);
margin-left: autoPx(5);
}
}
.notice_right {
height: autoPx(40);
line-height: autoPx(40);
width: calc(100% - (autoPx(60)));
// width: calc(100% - (autoPx(110)));
::v-deep .medium {
padding: 0 autoPx(10);
font-size: autoPx(13);
font-weight: 500;
text-align: left;
height: autoPx(40);
line-height: autoPx(40);
width: 100%;
position: absolute;
// text-overflow: ellipsis; /*让截断的文字显示为点点。还有一个值是clip意截断不显示点点*/
white-space: nowrap; /*让文字不换行*/
// overflow: hidden; /*超出要隐藏*/
// z-index: -1;
// transition: all .5s;
}
}
.notice_more {
height: autoPx(40);
line-height: autoPx(40);
padding: 0 autoPx(8);
font-size: autoPx(13);
cursor: pointer;
}
}
</style>
页面中使用组件:
import Gonggao from "./gonggao.vue";
components: { Gonggao },
<Gonggao :gg="ggList"></Gonggao>
备注:
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
- window.requestAnimationFrame()
返回值
:是个非零值( long 整数),请求 ID ,是回调列表中唯一的标识。可以传这个值给window.cancelAnimationFrame()
以取消回调函数。