使用 React 函数组件实现目录定位(滚动高亮)的完整示例。这个示例包含一个简单的页面,页面上有多个内容部分和一个侧边目录,用户可以点击目录项以滚动到对应的内容部分,并且在滚动时高亮当前的目录项。
时间: 2024-10-23 08:12:00 浏览: 13
在React中,我们可以创建一个函数组件,利用React Hooks(如useState和useRef)以及生命周期方法(如componentDidUpdate)来实现实现目录定位和滚动高亮的效果。以下是一个简单的示例:
首先,我们需要导入必要的库:
```jsx
import React, { useState, useRef, useEffect } from 'react';
```
然后,创建一个`ContentSection`组件,它将用于渲染每个内容部分:
```jsx
const ContentSection = ({ title, content }) => {
const id = `content-section-${title}`;
return (
<section id={id}>
<h2>{title}</h2>
<p>{content}</p>
</section>
);
};
```
接着,创建一个`DirectoryList`组件,负责展示目录:
```jsx
const DirectoryList = ({ items, setActiveItem }) => {
const [activeItem, setActiveItemRef] = useState(null);
const handleItemClick = (itemId) => {
setActiveItem(itemId);
};
return (
<ul>
{items.map((item, index) => (
<li
key={index}
onClick={() => handleItemClick(index)}
className={activeItem === index ? 'active' : ''}
>
{item}
</li>
))}
</ul>
);
};
```
最后,我们将这两个组件结合在一起,并在`App`组件中使用:
```jsx
function App() {
const [activeContentIndex, setActiveContentIndex] = useState(null);
const contentSections = [
{ title: '内容部分1', content: '这是第一部分的内容' },
{ title: '内容部分2', content: '这是第二部分的内容' },
// 更多内容...
];
const contentSectionsRef = useRef([]);
useEffect(() => {
contentSections.forEach((section, index) => {
contentSectionsRef.current[index] = useRef({ offsetTop: 0 });
});
setActiveContentIndex(activeContentIndex); // 初始化高亮
// 更新滚动位置时更新高亮状态
const handleScroll = () => {
let activeSection = null;
for (let i = 0; i < contentSectionsRef.current.length; i++) {
if (window.scrollY >= contentSectionsRef.current[i].current.offsetTop) {
activeSection = i;
break;
}
}
if (activeSection !== activeContentIndex) {
setActiveContentIndex(activeSection);
}
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [activeContentIndex, contentSections]);
return (
<div>
<DirectoryList
items={['目录项1', '目录项2', /* ... */]}
setActiveItem={(index) => setActiveContentIndex(index)}
/>
{contentSections.map((section, index) => (
<ContentSection
key={index}
title={section.title}
content={section.content}
ref={(ref) => contentSectionsRef.current[index] = ref}
/>
))}
</div>
);
}
export default App;
```
在这个示例中,每当目录项被点击或窗口滚动时,都会检查当前滚动位置并调整高亮的目录项。
阅读全文