I use useIntersectionObserver
from VueUse to trigger a fade-in animation when an element enters the viewport. If I navigate to another page (e.g., click on an item in the carousel to view its details) and then go back to previous route with the saved position, the intersection observer doesn’t trigger automatically, and the elements remain hidden unless I scroll the page down and up or refresh it. Also, if I scroll to the carousel, click on the carousel item and navigate to another route, the observer fails to trigger sometimes as well. So it’s not only an issue when returning to a route, but also after scrolling and navigating away.
To hide the elements before the observer activates, I use the invisible
class, which includes visibility: hidden
and opacity: 0
. The issue seems to be that intersection observer doesn’t detect the elements when visibility: hidden
is applied, so the fade-in animation never starts when returning to the page.
Observer.vue:
<template>
<div ref="observerRef">
<slot :isVisible="isVisible" />
</div>
</template>
<script setup>
import { useIntersectionObserver } from '@vueuse/core';
const props = defineProps({
rootMargin: {
type: String,
default: '0px',
},
});
const observerRef = ref(null);
const isVisible = ref(false);
const { stop } = useIntersectionObserver(
observerRef,
([{ isIntersecting }]) => {
if (isIntersecting) {
isVisible.value = isIntersecting;
stop();
}
},
{
rootMargin: props.rootMargin,
}
);
</script>
Component where I use intersection observer:
<ItemObserver v-slot="{ isVisible }">
<div :class="isVisible ? 'fade-in' : 'invisible'">
<CarouselContent>
<CarouselItem v-for="item in 8" :key="item">
<NuxtLink
to="/">
Link
</NuxtLink>
</CarouselItem>
</CarouselContent>
</div>
</ItemObserver>
css:
@keyframes fadeIn {
from {
visibility: hidden;
opacity: 0;
}
to {
visibility: visible;
opacity: 1;
}
}
.fade-in {
visibility: hidden;
opacity: 0;
animation: fadeIn 0.3s cubic-bezier(0.5, 0, 0.5, 1) forwards;
}
.invisible {
visibility: hidden;
opacity: 0;
}
Looking for a possible solution.