Пересечение Обозреватель - выделить текущий раздел - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь активировать и деактивировать класс для элементов навигационной панели всякий раз, когда раздел либо частично в поле зрения, либо частично вне поля зрения.Код работает нормально, если я прокручиваю страницу вниз или вверх полностью.Проблема в том, что если я поменяю направление в середине раздела.

Кажется, что сначала раздел должен быть вне поля зрения на 100%, а затем снова возвращаться в поле зрения, чтобы класс активировал или деактивировал (Я полагаю, что это происходит, потому что мы проверяем, является ли entry.isIntersecting истинным, и сначала его нужно изменить на ложное).Тем не менее, это приводит к нежелательному поведению.

Я пытался поиграть с оператором if, чтобы проверить с entry.intersectionRatio, но я не могу заставить его работать.Я также пробовал в разных браузерах, на всякий случай, но поведение остается тем же.

Как мне обойти это?

Вот некоторый код , который показывает это "глючное" поведение.Выглядит это так:

const sections = document.querySelectorAll('div.screen');
const config = {
  rootMargin: '-50px 0px -55%'
};

let observer = new IntersectionObserver(function (entries, self) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      intersectionHandler(entry); 
    }
  });
}, config);

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

function intersectionHandler(entry) {
  const id = entry.target.id;
  const currentlyActive = document.querySelector('nav li.active');
  const shouldBeActive = document.querySelector('nav li[data-ref=' + id + ']');

  if (currentlyActive) {
    currentlyActive.classList.remove('active');
  }
  if (shouldBeActive) {
    shouldBeActive.classList.add('active');
  }
}

Кодовая ручка от этой статьи.

Заранее спасибо.

1 Ответ

0 голосов
/ 24 апреля 2019

Я играл с вашим CodePen и нашел способ исправить проблему.

Основная идея - убедиться, что в root одновременно может быть только один элемент.Для этого вам нужно сделать две вещи:

Во-первых, высота rootMargin должна быть как можно меньше.

rootMargin: '-45% 0px -55%'

Я не уверен, что это верно, хотя ... Более правильный путь был бы:

var vh = document.documentElement.clientHeight;
var topMargin = Math.ceil(-0.45*vh);
var botMargin = Math.ceil(-0.55*vh);
...
rootMargin: topMargin + "px 0px " + botMargin + "px";

Второе - добавить маржу к вашему .screen CSS.class.

  margin-top: 3px;

(1 или 2 px может быть слишком маленьким)

Код работал нормально с Firefox и Chrome, но не работал на Safari, который, кажется, не реализуетAPI InstersectionObserver.У меня нет Windows, поэтому я не могу проверить Edge и IE.

...