滑动分栏
<div class="detil-main">
<a-tabs
:activeKey="currentTab"
tab-position="left"
@change="scrollToSection"
>
<a-tab-pane key="baseInfo" tab="a"></a-tab-pane>
<a-tab-pane key="channel" tab="b"></a-tab-pane>
<a-tab-pane key="derma" tab="c"></a-tab-pane>
</a-tabs>
<div
class="scroll-container"
ref="scrollContainer"
@scroll="handleScroll"
>
<div id="baseInfo" class="section">
<BaseInfo></BaseInfo>
</div>
<div id="channel" class="section">
<Channel></Channel>
</div>
<div id="derma" class="section">
<Derma></Derma>
</div>
</div>
</div>
<script lang="ts">
import BaseInfo from './BaseInfo.vue'
import Channel from './Channel.vue'
import Derma from './Derma.vue'
import { reactive, toRefs, ref, defineComponent } from 'vue'
export default defineComponent({
components: {
BaseInfo,
Channel,
Derma
},
setup(props, beds) {
const currentTab = ref('baseInfo')//定义分栏默认
const scrollContainer = ref<HTMLElement | null>(null)
const scrollToSection = (activeKey: string) => {
const sectionElement = document.getElementById(activeKey)
if (sectionElement && scrollContainer.value) {
//scrollIntoView是一个JavaScript方法,可以将元素滚动到可视区域内。你可以在Vue 3中使用ref来获取元素的引用,并调用scrollIntoView方法来实现滚动效果。
//注意!!使用选项{ behavior: 'smooth' }可以实现平滑滚动效果。但这个操作是异步的会跟handleScroll 冲突。用auto可以避免
sectionElement.scrollIntoView({ behavior: 'auto', block: 'start' })
currentTab.value = activeKey
}
}
const handleScroll = () => {
const sections = document.querySelectorAll('.section')
const observerOptions = {
root: scrollContainer.value,
rootMargin: '-50% 0% -50% 0%' // 自定义可见性区域
}
sections.forEach((section) => {
//IntersectionObserver解释在下面
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
currentTab.value = entry.target.id
}
})
}, observerOptions)
observer.observe(section)
})
}
return {
closeDialog,
currentTab,
scrollContainer,
scrollToSection,
handleScroll
}
}
})
</script>
IntersectionObserver是一个Web API,它可以用于异步监测目标元素与其祖先或视窗(viewport)之间的交叉状态。通过使用IntersectionObserver,开发者可以轻松地检测一个元素是否进入了视窗(或者另一个指定的元素),或者元素何时离开了视窗。这在实现无限滚动、延迟加载、懒加载等方案时非常有用。
使用IntersectionObserver的基本步骤如下:
- 创建一个IntersectionObserver对象,传入一个回调函数和一些配置选项。
- 使用该IntersectionObserver对象观察目标元素(或者视窗)。
- 当目标元素的交叉状态发生变化时,回调函数将被触发。
回调函数接收一个entries数组作为参数,每个entry表示一个目标元素与祖先(或视窗)的交叉信息。在回调函数中,你可以根据entry的属性(如isIntersecting、intersectionRatio等)来执行相应的操作。
IntersectionObserver API的使用相对于传统的滚动事件或resize事件更加高效和性能友好。由于它是异步执行的,可以避免不必要的计算和频繁的事件触发。
需要注意的是,IntersectionObserver在旧版浏览器中不被支持。但可以通过使用polyfill来提供对旧版浏览器的支持。