dogram99
@dogram99
Frontend-разработчик

Как узнать прокручен ли скролл до нужного элемента?

В общем, нужно что бы при прокрутке подсвечивался пункт меню в зависимости от нахождения скролла, главное сложность в том что есть большая вложенность и чекать компоненты через 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>
  • Вопрос задан
  • 239 просмотров
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы