Glayclik
@Glayclik
Начинаю по новой

Как правильно вызвать callback во время события scroll?

Здравствуйте!
Учусь JS, для пет-проджекта хочу реализовать следующее:
Картинка верстки

5f34087505fa2416671616.png

Что должно происходить
5f3408db5608a226143082.png

Codepen демонстрация


И еще раз на словах: во время пересечения заголовком определенной координаты, нужно в навигации слева менять класс. (вызвать тот самый callback)

Два дня страдаю над этим, что только не пробовал, скорее всего в корне подход избрал не верный. Посему, прошу помочь.
Координаты заголовка получаю методом:
element.getBoundingClientRect()

Тупой подход, для понимания в коде что должно происходить во время события scroll:

scrollObject.addEventListener('scroll', (evt) => {
  let coord = round(-section.getBoundingClientRect().y)
  let i = 0

  if (coord > 350) {
    addActiveClass(i)
    i++
  } else if (coord < 350) {
    removeActiveClass(i)
    i--
  } 
  if (coord > 750) {
    addActiveClass(i)
    i++
  } else if (coord < 750) {
    removeActiveClass(i)
    i--
  }
})



Всем неравнодушным огромное спасибо! :)
  • Вопрос задан
  • 192 просмотра
Пригласить эксперта
Ответы на вопрос 3
@lookfortheroot
Frontendman
Если вы не против другого подхода, то намного проще сделать связь элементов.
Скажем, заголовок с атрибутом data-id="2020", и в навигации data-id="2020".
Далее при прокрутке к заголовку получаем такой же id в навигации и делаем что нужно.
Ответ написан
twobomb
@twobomb
Можно типа такого

Тут можно поправить типа
if(sumHeight -30 >= scrollTop)
крч посмотреть
Ответ написан
Комментировать
@100380
Возможно это поможет.

Не оптимизировано, но логика, надеюсь, будет ясна.

1. Собираешь все свои секции за которыми надо следить.
2. Вешаешь обработчик события на скролл ноду - в нашем случае window, но можно докрутить и до контенра на странице с внутренним скролом. Но в таком случае надо будет расчитывать координаты относительно родителя.
3. При каждом скролле проходишь по массиву секций и выясняешь зашла ли она за указанное в offset расстояние по вертикали (сверху 0), для примера середина экрана window.innerHeight/2, и не поднялся ли низ секции из того же офсета (некоторые браузеры могут ругаться на отсутсвующее свойство .bottom в результате getBoundingClientRect(), поэтому в примере bb.top + bb.height). Это нужно для деактивации пункта навигации - одна зашла - другие вышли.
4. Цепляешь класс .active если секция вошла по data-id => data-nav-id если его нет еще или снимаешь его если он есть.



Обязательно нужен дебаунс на скролле хотя бы в 100ms.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы