When utilizing useIntersectionObserver
from VueUse to trigger a fade-in animation upon an element entering the viewport, I encountered a specific issue. Upon navigating to another page or clicking on an item in the carousel and then returning to the previous route with the saved position, the intersection observer fails to trigger automatically. This results in elements remaining hidden unless the page is manually scrolled up and down or refreshed. Additionally, there are instances where if I navigate away after scrolling to the carousel and returning, the observer may not trigger as expected. So the challenge extends beyond just returning to a route but also affects situations involving scrolling and navigation.
To handle the visibility of elements before the observer activation, I apply the invisible
class which includes properties like visibility: hidden
and opacity: 0
. The root cause appears to be the intersection observer's inability to detect elements when the visibility: hidden
property is active. Consequently, this prevents the initiation of the fade-in animation upon returning to the page.
To see a demonstration, you can visit: . In the demo, I navigate to the /details
route and then return followed by a page reload.
Regarding the Observer.vue code snippet:
<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>
The component where the intersection observer is utilized:
<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 styles used:
@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;
}
If anyone has suggestions for resolving this issue, please share your thoughts!