import'./index.less';importAnchor from './Anchor';importContent from './Content';exportdefault function index(){return(<div className="wrapper"><div className="header"></div><div className="content-wrapper">// 锚点组件<Anchor />// 页面内容组件<Content /></div><div className="footer"></div></div>);}
锚点组件
importReact,{ useState, useEffect, useRef } from 'react';exportdefault function Anchor(){const[currentIndex, setCurrentIndex]=useState(0);const isClickRef =useRef<any>(null);const timerRef =useRef<any>(null);const anchorList =['anchor-1','anchor-2','anchor-3','anchor-4'];function onClickAnchor(item: string, index: number){const el = document.querySelector(`#${item}`) as HTMLElement;if(el){window.scroll({top: el.offsetTop -130,behavior:'smooth',});}setCurrentIndex(index);// 点击时设置为true,为了防止同时执行滚动事件isClickRef.current =true;// 清除定时器,防止滚动事件触发、出现走马灯闪烁问题if(timerRef.current)clearTimeout(timerRef.current);timerRef.current =setTimeout(()=>{isClickRef.current =false;},1000);}function handlerScroll(){// 点击锚点时,不执行滚动函数if(isClickRef.current)return;// 获取滚动容器的滚动高度(这里相对于body滚动的)const scrollTop =document.documentElement.scrollTop || document.body.scrollTop;// 获取所有content的item集合const contentList = document.querySelectorAll('.content div') as any;const offsetTopArr: any =[];contentList?.forEach((item: any)=>{// 获取每个content中item的offsetTopoffsetTopArr.push(item.offsetTop);});for(let i =0; i < offsetTopArr.length; i++){// 当滚动条高度达到对应content中item的滚动高度、则将锚点设置为高亮状态if(scrollTop +120>= offsetTopArr[i]){setCurrentIndex(i);}}}useEffect(()=>{window.addEventListener('scroll', handlerScroll);return()=>{window.removeEventListener('scroll', handlerScroll);};},[]);return(<div className="anchor-wrapper">{anchorList?.map((item, index)=>(<divkey={item}className={`${currentIndex === index &&'active'} item`}onClick={()=>onClickAnchor(item, index)}>{item}</div>))}<divclassName={`slide-bar slide-bar-${currentIndex}`}style={{ top: `${currentIndex *60}px` }}></div></div>);}
页面内容组件
importReact from 'react';exportdefault function Content(){const contentList =[{ id:'anchor-1', content:'content-1'},{ id:'anchor-2', content:'content-2'},{ id:'anchor-3', content:'content-3'},{ id:'anchor-4', content:'content-4'},];return(<div className="content">{contentList?.map((item, index)=>(<div key={index} id={item.id} className="item">{item.content}</div>))}</div>);}