实现滑动切换左侧导航栏,点击滑动至指定位置
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; }