Vue intersectionobserver верхнее пересечение
как сделать отслеживание пересечения с шапкой и такое изменение в фиксированном блоке, как на видео
мой код
шаблон вывода постов (посты подгружаю по одному)
<template>
<div
v-for="article in articles"
:key="article.content.id"
ref="articlesRef"
:data-id="article.content.id">
<ArticleContent :article="article" />
</div>
<LazyCommonLoader v-if="isPendingNextArticle" />
<div
ref="intersectionElement"
class="my-6 text-center mx-0 lg:ml-[102px] lg:mr-[305px]">
<div class="h-px"></div>
</div>
</template>
переменные
const articlesRef = ref();
const options = {
root: null,
rootMargin: '0px',
threshold: 0.5,
};
const lastId = ref();
const intersectionElement = ref();
const intersectionObserver = ref<IntersectionObserver | null>(null);
const intersectionObserverTop = ref<IntersectionObserver | null>(null);
инициализация observer для подгрузки новой статьи при скролле вниз
onMounted(() => {
intersectionObserver.value = new IntersectionObserver(
handleIntersection,
options
);
intersectionObserver.value.observe(intersectionElement.value);
});
callback observer
const handleIntersection = (entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
loadNextArticles();
}
});
};
функция подгрузки статьи
const loadNextArticles = async () => {
const lastArticle = articles.value[articles.value.length - 1];
if (lastId.value === lastArticle.content.id) {
return;
}
lastId.value = lastArticle.content.id;
const response = await fetchNextArticle({
articleId: lastId.value,
});
if (!response) {
return;
}
articles.value.push({
content: response,
});
};
теперь по вопросу накидал watch для наблюдением и подпиской в observer новых статей
watch(
() => articlesRef.value,
() => {
articlesRef.value.forEach((articleElement) => {
intersectionObserverTop.value?.unobserve(articleElement);
});
articlesRef.value.forEach((articleElement) => {
intersectionObserverTop.value.observe(articleElement);
});
},
{
deep: true,
}
);
инициализация второго observer
onMounted(() => {
intersectionObserverTop.value = new IntersectionObserver(
handleIntersectionTop,
{
root: null,
rootMargin: `0px`,
threshold: 0,
}
);
});
callback
const handleIntersectionTop = (entries: IntersectionObserverEntry[]) => {
entries.forEach((entry, index) => {
if (entry.boundingClientRect.top <=0) {
console.log(entry.target);
}
});
};
и здесь затуп, так как выводит по несколько блоков сразу при срабатывании observer