实现滑动切换左侧导航栏,点击滑动至指定位置
import React, { useEffect, useRef, useState } from 'react'
import { SideBar } from 'antd-mobile'
import "./css/louce.css"
import { useThrottleFn } from 'ahooks'
const Louce = () => {
const items = [
{ key: '1', title: '第一项', text: [{ _id: "1", name: "商品1" }, { _id: "11", name: "商品12" }, { _id: "2", name: "商品13" }, { _id: "12", name: "商品14" }, { _id: "13", name: "商品15" }, { _id: "14", name: "商品16" }] },
{ key: '2', title: '第二项', text: [{ _id: "1", name: "商品1" }, { _id: "11", name: "商品12" }, { _id: "2", name: "商品13" }, { _id: "12", name: "商品14" }, { _id: "13", name: "商品15" }, { _id: "14", name: "商品16" }] },
{ key: '3', title: '第三项', text: [{ _id: "1", name: "商品1" }, { _id: "11", name: "商品12" }, { _id: "2", name: "商品13" }, { _id: "12", name: "商品14" }, { _id: "13", name: "商品15" }, { _id: "14", name: "商品16" }] },
{ key: '4', title: '第四项', text: [{ _id: "1", name: "商品1" }, { _id: "11", name: "商品12" }, { _id: "2", name: "商品13" }, { _id: "12", name: "商品14" }, { _id: "13", name: "商品15" }, { _id: "14", name: "商品16" }] },
]
const [activeKey, setActiveKey] = useState('1')
const { run: handleScroll } = useThrottleFn(
() => {
let currentKey = items[0].key
for (const item of items) {
const element = document.getElementById(`anchor-${item.key}`)
if (!element) continue
const rect = element.getBoundingClientRect()
if (rect.top <= 0) {
currentKey = item.key
} else {
break
}
}
setActiveKey(currentKey)
},
{
leading: true,
trailing: true,
wait: 100,
}
)
const mainElementRef = useRef()
useEffect(() => {
const mainElement = mainElementRef.current
if (!mainElement) return
mainElement.addEventListener('scroll', handleScroll)
return () => {
mainElement.removeEventListener('scroll', handleScroll)
}
}, [])
return (
<div>
<div className="container">
<div className="side">
<SideBar
activeKey={activeKey}
onChange={key => {
document.getElementById(`anchor-${key}`)?.scrollIntoView()
}}
>
{items.map(item => (
<SideBar.Item key={item.key} title={item.title} />
))}
</SideBar>
</div>
<div className="main" ref={mainElementRef}>
{items.map(item => (
<div key={item.key} className='mitem'>
<h2 id={`anchor-${item.key}`}>{item.title}</h2>
<div className='items'>
{item.text.map(itm => {
return (
<div>
{itm.name}
</div>
)
})}
</div>
</div>
))}
</div>
</div>
</div>
);
}
export default Louce;
css样式
.container {
height: 100vh;
background-color: #ffffff;
display: flex;
justify-content: flex-start;
align-items: stretch;
}
.side {
flex: none;
}
.main {
flex: auto;
padding: 0 24px 32px;
overflow-y: scroll;
}
h2 {
margin: 0;
padding: 12px 0;
}
.mitem{
height: 100vh;
}
.items{
display: flex;
flex-wrap: wrap;
}
.items>div{
width: 100px;
line-height: 50px;
}