Почему возникает проблема scrollBy в присутствии IntersectionObserver?

Всем здравствуйте. Задача следующая:

Иметь на странице IntersectionObserver для переключения активных пунктов меню.

Иметь на странице scrollBy для плавного скролла по якорям. Увидел такую проблему: scrollBy прокручивает до элемента неверно, немного путая координаты, нажимая второй раз на ту же кнопку - скролл верно встаёт на позицию. Когда удаляю код IntersectionObserver, то такой баг пропадает, scrollBy прокручивает сразу как положено.

document.addEventListener("DOMContentLoaded", function(){
  const sections = document.querySelectorAll("[data-observer-section]");
  const navs = document.querySelectorAll("[data-observer-nav]");
  setActiveLink();
  window.addEventListener('hashchange', setActiveLink);

  // Прокрутка к элементу
  navs.forEach(nav => {
    nav.addEventListener('click', function(e) {
        e.preventDefault();    
        const href = this.getAttribute('href').substring(1);    
        const scrollTarget = document.querySelector("#" + href);    
        const elementPosition = scrollTarget.getBoundingClientRect().top;
        const offsetPosition = elementPosition - topOffset;    
        console.log(elementPosition)
        window.scrollBy({
            top: offsetPosition,
            behavior: 'smooth'
        }); 
    });
  });

const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {            
        if(entry.isIntersecting ) {                
            location.hash = entry.target.getAttribute("id");
        }
    });    
  }, {  threshold: 0.55, rootMargin: sensitivity + "px" });       

sections.forEach( section => {
    observer.observe(section);
});

function setActiveLink(){ 
    let hash = location.hash;
    console.log(hash)
    navs.forEach(nav => {
        if (nav.getAttribute("href") === hash) {
            nav.classList.add("active");
            nav.scrollIntoView({ inline: "center"});
        } else {
            nav.classList.remove("active");
        }
    });
}});
  • Вопрос задан
  • 221 просмотр
Пригласить эксперта
Ответы на вопрос 1
GogElf
@GogElf
Хокаге
Когда вы используете window.scrollBy на это реагирует IntersectionObserver и изменяет hash в адресе страницы, на это реагирует событие hashchange которое вызывает функцию setActiveLink которая в свою очередь вызывает nav.scrollIntoView({ inline: "center"});. Следовательно nav.scrollIntoView создает эту проблему.
А при повторном нажатии IntersectionObserver не отрабатывает так как объект и так в зоне видимости.
Ответ написан
Ваш ответ на вопрос

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

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