create-react-app #创建react项目
npm i lorem-ipsum #控制内容显示大小
npm install --save antd-mobile #移动端组件
HTML代码:
import React, { useEffect, useRef, useState } from 'react'
import { SideBar } from 'antd-mobile'
import styles from './index.less'
import { LoremIpsum } from 'lorem-ipsum'
const lorem = new LoremIpsum({
sentencesPerParagraph: {
max: 8,
min: 4,
},
wordsPerSentence: {
max: 16,
min: 4,
},
})
const items = [
{ key: '1', title: '第一项', text: lorem.generateParagraphs(8) },
{ key: '2', title: '第二项', text: lorem.generateParagraphs(8) },
{ key: '3', title: '第三项', text: lorem.generateParagraphs(8) },
{ key: '4', title: '第四项', text: lorem.generateParagraphs(8) },
]
export default () => {
return (
<div className={styles.container}>
<div className={styles.side} style={{display:'flex'}}>
<SideBar
style={{position:'fixed'}}
className={styles.bar}
activeKey={activeKey}
onChange={key => {
window.document.getElementById(`anchor-${key}`)?.scrollIntoView()
}}
>
{items.map(item => (
<SideBar.Item key={item.key} title={item.title} />
))}
</SideBar>
<div className={styles.main} style={{width:'65%',marginLeft:'106px'}} ref={mainElementRef}>
{items.map(item => (
<div key={item.key} className={styles.main_content}>
<h2 id={`anchor-${item.key}`}>{item.title}</h2>
{item.text}
</div>
))}
</div>
</div>
</div>
)
}
JS代码:
const [activeKey, setActiveKey] = useState('1')
const handleScroll = () => {
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)
}
const mainElementRef = useRef(null)
useEffect(() => {
const mainElement = mainElementRef.current
if (!mainElement) return
document.addEventListener('scroll', handleScroll)
return () => {
document.removeEventListener('scroll', handleScroll)
}
}, [])
侧边导航与右侧页面内容效果