Как узнать направление прокрутки 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>