记录一下有意思的思路
上班遇到需要完成列表滚动并高亮对应菜单栏的需求
滚动思路:先获取列表的每一项小容器的offsetTop和浏览器滚动条的滚动高度相减,得到每一个相减的绝对值,绝对值越小就说明该容器越接近当前显示的屏幕区域,再根据该下标就可以知道当前需要高亮的菜单栏是哪一项。
菜单点击思路:获取菜单栏当前点击的index,滚动到对应的列表的offsetTop即可
直接上代码
<template>
<div class="content-container">
<div class="aside">
<el-menu :default-active="activeIndex" class="el-menu-vertical-demo aside-menu" @select="handleSelect">
<el-menu-item index="0">
<i class="el-icon-menu"></i>
<span slot="title">导航一</span>
</el-menu-item>
<el-menu-item index="1">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</div>
<div class="content">
<div class="box" ref="content">
<div class="item" :id="`item${index}`" v-for="(item, index) in contentList">{{ item }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Content',
data() {
return {
contentList: ['1', '2', '3', '4'],
activeIndex: '0',
content: ''
}
},
methods: {
/**
* 滚动事件
*/
handleScroll(e) {
/* *
* 获取每个.item的offsetTop
* 与滚动高度相减的绝对值的下标和哪个菜单栏index最近
* 就高亮哪个菜单项
* */
let scroll = this.$refs.content.scrollTop
let arr = Array(4)
.fill(0)
.map((item, index) => {
let contentItem = document.getElementById(`item${index}`)
return Math.abs(scroll - contentItem.offsetTop)
})
this.activeIndex = arr.indexOf(Math.min(...arr)) + ''
},
handleSelect(index) {
let contentItem = document.getElementById(`item${index}`)
this.$refs.content.scrollTo({
top: contentItem.offsetTop,
behavior: 'smooth'
})
}
},
mounted() {
this.$nextTick(() => {
this.$refs.content.addEventListener('scroll', this.handleScroll)
})
},
beforeDestroy() {
this.$refs.content.removeEventListener('scroll', this.handleScroll)
}
}
</script>
<style scoped>
.content-container {
display: flex;
justify-content: space-between;
overflow: hidden;
}
.aside {
width: 200px;
}
.aside-menu {
position: fixed;
top: 0;
left: 0;
width: 200px;
height: 100vh;
}
.content {
flex: 1;
font-size: 32px;
text-align: center;
overflow: hidden;
}
.content .box {
width: 100%;
height: 100vh;
overflow: auto;
}
.content .box .item {
height: 900px;
background: #ec4141;
margin-bottom: 10px;
}
</style>