<template>
<div class="lab-group-switch">
<ul>
<template v-for="(group, index) in labGroups">
<li
:key="index"
class="week-num relative"
:class="{ 'active': activeIndex === index }"
@click="switchGroup(index)"
>
<span>{{ index }}周</span>
<span class="week-title">
{{ group.name }}
</span>
</li>
</template>
<li
v-show="!isPositionTop"
class="week-num relative"
@click="backTop"
>
<img
src="~assets/images/pages/courses/labs/icon-top.png"
alt=""
>
<span class="week-title">
回到顶部
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
labGroups: {
type: Array,
default: () => [],
},
},
data() {
return {
isPositionTop: true,
activeIndex: 0,
labListContainer: null,
weekNodeList: [],
timer: 0,
}
},
mounted() {
if (document.documentElement.scrollTop > 0) {
this.isPositionTop = true
} else {
this.isPositionTop = false
}
let nodeList = []
for (let index = 0; index < this.labGroups.length; index++) {
const node = document.querySelector(`#week-${index}`)
nodeList.push(node)
}
this.nodeList = nodeList
this.labListContainer = document.querySelector('.course-lab-list-container')
window.addEventListener('scroll', this.handleScroll)
},
destroyed() {
// 移除滚动监听
window.removeEventListener('scroll', this.handleScroll)
},
methods: {
// 分组切换
switchGroup(index) {
if (this.activeIndex === index) {
return
}
this.activeIndex = index
const node = document.querySelector(`#week-${index}`)
const windowScrollHeight = document.documentElement.scrollTop
const nodeOffsetTop = node.getClientRects()[0].top
let scrollTop = 0
document.documentElement.scrollTop =
windowScrollHeight + nodeOffsetTop - 100
},
// 回到顶部
backTop() {
document.documentElement.scrollTop = 0
this.activeIndex = 0
},
// 处理滚动事件
handleScroll() {
if (!!this.labListContainer.style.display) {
return
}
if (document.documentElement.scrollTop > 0) {
this.isPositionTop = false
} else {
this.isPositionTop = true
}
if (this.timer) {
return
}
// 100 ms 执行一次
this.timer = setTimeout(() => {
this.nodeList.map((node, index) => {
const nodeOffsetTop = node.getClientRects()[0].top
if (nodeOffsetTop < 120) {
this.activeIndex = index
}
})
this.timer = 0
}, 100)
},
},
}
</script>
<style lang="scss" scoped>
.lab-group-switch {
position: fixed;
left: 10px;
width: 50px;
top: 100px;
padding: 5px 6px;
list-style: none;
border-radius: 5px;
background-color: #fff;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
z-index: 9;
> ul {
padding: 0;
margin: 0;
list-style: none;
> li {
position: relative;
height: 40px;
padding-top: 10px;
font-size: 0.9rem;
text-align: center;
color: #999;
border-bottom: 1px solid #eee;
cursor: pointer;
&.active {
color: #08bf91;
}
.week-title {
position: absolute;
opacity: 0;
visibility: hidden;
left: 20px;
top: 5px;
padding: 5px 15px;
background: #fff;
border: 1px solid #eee;
border-radius: 5px;
font-size: 12px;
white-space: nowrap;
text-align: left;
color: #08bf91;
transition: all 0.3s ease-out;
pointer-events: none;
&::after {
content: '';
position: absolute;
left: -6px;
top: 35%;
background: #fff;
height: 10px;
width: 10px;
transform: rotateZ(45deg);
border-left: 1px solid #eee;
border-bottom: 1px solid #eee;
}
}
&:hover {
.week-title {
visibility: visible;
opacity: 1;
left: 50px;
}
}
}
}
}
</style>
网友评论