今天改别人写好的页面的bug,遇到一个需求,需求描述:模块导航栏:滑动到顶部后,悬浮固定,点击可切换至对应模块,导航栏有吸顶效果。
(代码过于长 只截取一个模块的写法举例)
原来的写法
tab部分 点击菜单模块传item
<div class="anchorContent">
<el-divider direction="vertical" />
<template v-for="item in pointList" :key="item.id">
<el-button
link
:type="currKey === item.title ? 'primary' : ''"
@click="clickKey(item)"
>{{ item.title }}</el-button
>
<el-divider direction="vertical" />
</template>
</div>
html
<div
class="cardContent"
style="background-color: #ffffff"
id="resourceType"
>
<h2>资源类型</h2>
<ResourceData />
</div>
css
.cardContent {
position: relative;
padding: 70px 0;
margin: 0 auto;
.proContent {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-top: 48px;
.productPrice {
width: 292px;
margin-right: 33px;
margin-bottom: 30px;
}
.productPrice:nth-child(2n) {
margin-right: 0;
}
}
}
ts
// resourceType到顶部的距离
const resourceTypeScroll = ref<number>(0)
// summaryId到顶部的距离
const summaryIdScroll = ref<number>(0)
// sceneId到顶部的距离
const sceneIdScroll = ref<number>(0)
// priceId到顶部的距离
const priceIdScroll = ref<number>(0)
// developerId到顶部的距离
const developerIdScroll = ref<number>(0)
// 组件的滚动到位置的标题
//滚动事件
const remoteSenseScroll = (e: Event) => {
if (e.target instanceof HTMLDivElement) {
// 获取每个id内容到顶部的距离 start
resourceTypeScroll.value = Number(
Number(document.getElementById('resourceTypes')?.offsetTop) - 128
)
summaryIdScroll.value = Number(
Number(document.getElementById('summaryIds')?.offsetTop) - 128
)
sceneIdScroll.value =
Number(document.getElementById('sceneIds')?.offsetTop) - 128
priceIdScroll.value =
Number(document.getElementById('priceIds')?.offsetTop) - 128
developerIdScroll.value = Number(
Number(document.getElementById('developerIds')?.offsetTop) - 128
)
// 获取每个id内容到顶部的距离 end
const { scrollTop } = e.target
if (scrollTop < 465) {
currKey.value = '0'
}
if (
scrollTop >= resourceTypeScroll.value &&
scrollTop < summaryIdScroll.value
) {
currKey.value = '资源类型'
}
if (scrollTop >= summaryIdScroll.value && scrollTop < priceIdScroll.value) {
currKey.value = '产品优势'
}
if (scrollTop >= priceIdScroll.value && scrollTop < sceneIdScroll.value) {
currKey.value = '产品价格'
}
if (
scrollTop >= sceneIdScroll.value &&
scrollTop < developerIdScroll.value
) {
currKey.value = '应用场景'
}
if (scrollTop >= developerIdScroll.value) {
currKey.value = '开发者资源'
}
}
}
// 锚点定位名字
let currKey = ref<string>('')
const clickKey = (key: { [key: string]: any }) => {
currKey.value = key.title
let scrollDom = document.getElementById(key.id)
scrollDom?.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'nearest'
})
}
点击菜单传递item,item中包含了模块的tittle,将tittle赋值给currkey,获取对应模块的dom 的id之后,scrollDom?.scrollIntoView方法可以滑动到对应的模块。
遇到的问题锚点定位不准确,跳转到菜单的部分会盖住标题
原因是
实际上顶部到达的位置是如图所示,盖住了标题,吸顶效果的tab栏盖住了标题。
解决办法
因为无法在原来的id所在的盒子里直接加上top
所以在标题前添加一个div用来定位,设置该盒子的top,让他离顶部有一些距离
代码
<div
class="cardContent"
style="background-color: #ffffff"
id="resourceTypes"
>
<div id="resourceType"></div> //在这添加一行
<h2>资源类型</h2>
<ResourceData />
</div>
css
#resourceType,
#summaryId {
position: absolute;
top: -123px;
}
解决