Как узнать направление прокрутки IntersectionObserver?

Итак, как узнать направление прокрутки при срабатывании события?

В возвращенном объекте ближайшая возможность, которую я вижу, взаимодействует с типом boundingClientRect сохранения последней позиции прокрутки, но я не знаю, закончится ли обработка boundingClientRect на проблемах производительности.

Можно ли использовать событие пересечения для определения направления прокрутки (вверх/вниз)?

Я добавил этот базовый фрагмент, поэтому, если кто-то может мне помочь.
Я буду очень благодарен.

Вот фрагмент:

var options = {
  rootMargin: '0px',
  threshold: 1.0
}

function callback(entries, observer) { 
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('entry', entry);
    }
  });
};

var elementToObserve = document.querySelector('#element');
var observer = new IntersectionObserver(callback, options);

observer.observe(elementToObserve);
#element {
  margin: 1500px auto;
  width: 150px;
  height: 150px;
  background: #ccc;
  color: white;
  font-family: sans-serif;
  font-weight: 100;
  font-size: 25px;
  text-align: center;
  line-height: 150px;
}
<div id="element">Observed</div>

Ответы

Ответ 1

:)

Я не думаю, что это возможно с одним пороговым значением. Вы можете попытаться следить за intersectionRatio, который в большинстве случаев находится под 1, когда контейнер покидает область просмотра (потому что наблюдатель пересечения запускает async). Я уверен, что это может быть 1, хотя если браузер быстро догонит. (Я не тестировал это: D)

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

threshold: [0.9, 1.0]

Если вы получили событие для 0.9, сначала ясно, что контейнер входит в область просмотра...

Надеюсь, это поможет.:)

Ответ 2

Сравнивая boundingClientRect и rootBounds с entry, вы можете легко узнать, находится ли цель выше или ниже области просмотра.

Во время callback() вы проверяете isAbove/isBelow, затем, в конце, вы храните его в wasAbove/wasBelow. В следующий раз, если цель появится в окне просмотра (например), вы можете проверить, было ли это выше или ниже. Значит, вы знаете, что оно происходит сверху или снизу.

Вы можете попробовать что-то вроде этого:

var wasAbove = false;

function callback(entries, observer) {
    entries.forEach(entry => {
        const isAbove = entry.boundingClientRect.y < entry.rootBounds.y;

        if (entry.isIntersecting) {
            if (wasAbove) {
                // Comes from top
            }
        }

        wasAbove = isAbove;
    });
}

Надеюсь, что это поможет.

Ответ 3

Мое требование:

  • ничего не делать при прокрутке
  • при прокрутке вниз, решите, начал ли элемент скрываться с экрана сверху

Мне нужно было увидеть несколько информации из IntersectionObserverEntry:

  • intersectionRatio (должно уменьшаться от 1.0)
  • boundingClientRect.bottom
  • boundingClientRect.height

Итак, обратный вызов выглядел так:

intersectionObserver = new IntersectionObserver(function(entries) {
  const entry = entries[0]; // observe one element
  const currentRatio = intersectionRatio;
  const newRatio = entry.intersectionRatio;
  const boundingClientRect = entry.boundingClientRect;
  const scrollingDown = currentRatio !== undefined && 
    newRatio < currentRatio &&
    boundingClientRect.bottom < boundingClientRect.height;

  intersectionRatio = newRatio;

  if (scrollingDown) {
    // it scrolling down and observed image started to hide.
    // so do something...
  }

  console.log(entry);
}, { threshold: [0, 0.25, 0.5, 0.75, 1] });

См. мой пост для полных кодов.

Ответ 4

Из этого Как определить направление события прокрутки jQuery?, а также ваш код, я сделал следующий код, попробуйте:

var options = {
  rootMargin: '0px',
  threshold: 1.0
               }

function callback(entries, observer) { 
  entries.forEach(entry => {
    if (entry.isIntersecting) {
    
  var scroll =document.getElementById("scroll").value;   
  console.log(entry.target.innerHTML+"  i am going   "+scroll);    
        
      
    }
  });
};


 var elementToObserve = document.querySelector('#element');
  var observer = new IntersectionObserver(callback, options);
    observer.observe(elementToObserve);
      
var x = 0;
$(window).scroll(function(event){
   var y = $(this).scrollTop();
     if (y > x){
     $("#scroll").val("up");              
      } else {
    $("#scroll").val("down");    
    
       }
      x = y;
    });
#element {
  margin: 1500px auto;
  width: 150px;
  height: 150px;
  background: #ccc;
  color: white;
  font-family: sans-serif;
  font-weight: 100;
  font-size: 25px;
  text-align: center;
  line-height: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div id="element">Observed</div>
<input type=hidden id=scroll>