一、IntersectionObserver
<template>
<div>
<div class="container">
<div>aaa</div>
<div>bbb</div>
<div>ccc</div>
<div>ddd</div>
<div>eee</div>
<div>fff</div>
</div>
</div>
</template>
<script setup>
import { onMounted } from "vue";
onMounted(() => {
const intersectionObserver = new IntersectionObserver((entries) => {
const intersectionEntry = entries.find((entry) => entry.isIntersecting);
if (intersectionEntry) {
console.log(intersectionEntry.target);
}
});
document.querySelector(".container").childNodes.forEach((child) => {
intersectionObserver.observe(child);
});
});
</script>
<style scoped>
.container {
border: 1px solid black;
width: 300px;
height: 600px;
overflow-y: auto;
}
.container > div {
height: 300px;
}
</style>
<template>
<div>
<el-tabs v-model="tabActive" @tab-click="handleTabClick">
<el-tab-pane
v-for="item of tabActives"
:key="item.id"
:name="item.id"
:label="item.label"
>
</el-tab-pane>
</el-tabs>
<div id="scrollContainer">
<div v-for="item of tabActives" :key="item.id" :id="item.id">
{{ item.label }}
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
const tabActives = ref([
{ label: "单位资料", id: "unitInformation" },
{ label: "建筑信息", id: "buildingInformation" },
{ label: "消防安全重点部位", id: "keyFireSafetyAreas" },
{ label: "单位危险品", id: "unitDangerousGoods" },
{ label: "位置地图", id: "locationMap" },
{ label: "视频", id: "companyVideo" },
{ label: "档案管理", id: "fileManagement" },
{ label: "值班人员", id: "operatorOnDuty" },
{ label: "微型消防站", id: "microFireStation" },
{ label: "应急预案", id: "emergencyPlan" },
]);
const tabActive = ref("unitInformation");
const scrollLock = ref(false);
const handleTabClick = () => {
const idObj = tabActives.value.find((item) => item.id === tabActive.value);
document.getElementById(idObj.id).scrollIntoView({ behavior: "smooth" });
scrollLock.value = true;
};
const listenScroll = () => {
const companyInfoScrollEl = document.getElementById("scrollContainer");
let scrollTimer = 0;
companyInfoScrollEl.onscroll = () => {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(() => {
if (scrollLock.value) {
scrollLock.value = false;
} else {
for (let i = 0; i < tabActives.value.length; i++) {
const el = document.getElementById(tabActives.value[i].id);
if (
el.offsetTop + el.offsetHeight / 2 >
companyInfoScrollEl.scrollTop
) {
tabActive.value = tabActives.value[i].id;
break;
}
}
}
}, 60);
};
};
onMounted(() => {
listenScroll();
});
</script>
<style scoped>
#scrollContainer {
border: 1px solid black;
width: 300px;
height: 600px;
overflow-y: auto;
}
#scrollContainer > div {
height: 300px;
}
</style>