В общем, нужно что бы при прокрутке подсвечивался пункт меню в зависимости от нахождения скролла, главное сложность в том что есть большая вложенность и чекать компоненты через
ref не удается, так как прокидывать его из дочернего компонента довольно проблематично, а затем еще на два уровня ниже надо спустить, а через
айдишники на сколько знаю плохая практика.
Поэтому хотел узнать есть ли какие-нибудь способы или только эти ?
Сейчас рабочий код выглядит примерно так, тут еще используется библиотека
react-router-hash-link, поэтому если компонент в зоне просмотра, то я пушу нужный hash как у якоря чтоб он сам применил
active класс к ссылке
const scrollHandler = useCallback(() => {
const MFE_Content: HTMLElement | null = document.getElementById("MFE_Content");
const StudyFAQ: HTMLElement | null = document.getElementById("studyFAQ");
const AskQuestion: HTMLElement | null = document.getElementById("askAquestion");
if (StudyFAQ && isInViewport(StudyFAQ)) {
history.push(EnrollmentPortalHomeAnchorRoutes.HOME_STUDY_FAQ);
} else if (AskQuestion && isInViewport(AskQuestion)) {
history.push(EnrollmentPortalHomeAnchorRoutes.HOME_ASK_A_QUESTION);
} else if (MFE_Content && isInViewport(MFE_Content)) {
history.push(EnrollmentPortalHomeAnchorRoutes.HOME_ANCHOR);
}
}, [history]);
Вот код проверки зоны видимости:
function isInViewport(el: HTMLElement): boolean {
const rect = el.getBoundingClientRect();
const elemTop = rect.top;
const elemBottom = rect.bottom;
const elemCenter = ((elemTop + elemBottom) / 2);
return (elemTop >= 0) && (elemCenter <= window.innerHeight);
}
А вот так выглядят ссылки:
<NavHashLink
smooth
className="nav-link"
to={'/home/#askAquestion'}
scroll={el => scrollWidthOffset(el)}>Ask a question</NavHashLink>