How to Track Element Visibility Using IntersectionObserver in Angular - Step by Step Guide
Table of contents
No headings in the article.
Greetings everyone !! As front-end developers, we often encounter the need to track when an element becomes visible within the viewport. However, this can be a challenging task without a reliable solution.
From MDN,
Historically, detecting the visibility of an element, or the relative visibility of two elements in relation to each other, has been a difficult task for which solutions have been unreliable and prone to causing the browser and the sites the user is accessing to become sluggish.
Fortunately, with advancements in technology, the IntersectionObserver API was introduced as a reliable solution to this problem.
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport - MDN
Join me as I walk you through a comprehensive step-by-step guide on how to effectively implement the IntersectionObserver functionality within an Angular application.
First, we will import the necessary modules and add a reference to the element we want to track using ViewChild.
The card.component.ts file should look something like this:
And the card.component.html file should look something like this:
To access the native element of the card component, we can use the ViewChild decorator available in Angular. This allows us to reference the element in our component's TypeScript file. Your code should now look like this -
The next step is to create a callback method that will be triggered when the element is visible in the viewport. You can do this by adding a method, such as
onIntersection()
, to the code. This method will be responsible for handling the visibility of the element and performing any necessary actions.The callback method will receive a list of IntersectionObserverEntry objects as its parameter. By checking the
isIntersecting
property on the first entry, we can determine if the element is currently visible within the viewport.Add a method on the ngOnInit lifecycle hook initializing the IntersectionObserver by passing the above-mentioned callback function and params.
this.observer = new IntersectionObserver(this.onIntersection.bind(this), { threshold: [0] });
To further customize the visibility detection, we can utilize the threshold parameter of the IntersectionObserver. This allows us to specify the percentage of the element that must be visible to trigger the callback. For example, setting a threshold of 0.5 means that 50% of the element must be visible. You can explore more configuration options by checking out the IntersectionObserver API documentation. Finally, we invoke the
observe
method on the initialized object to start tracking the element's visibility.if (this.card) { this.observer.observe(this.card.nativeElement); }
The updated code should now appear as follows:
To ensure efficient memory usage and prevent any potential errors, it is important to unobserve the IntersectionObserver when it is no longer needed. This can be done in the ngOnDestroy lifecycle method, which will be automatically called by Angular when the component is destroyed. Your code should now look like this:
Intersection information is needed for many reasons, such as:
Lazy-loading of images or other content as a page is scrolled.
Implementing "infinite scrolling" websites, where more and more content is loaded and rendered as you scroll so that the user doesn't have to flip through pages.
Reporting of visibility of advertisements to calculate ad revenues.
Deciding whether or not to perform tasks or animation processes based on whether or not the user will see the result.
You can read more about IntersectionObserver.
If you encounter any difficulties during the integration process, feel free to reach out to me via the comments section or on my social media profiles. And, if you're interested, let me know in the comments if you'd like me to create a video tutorial for this.
Hit the like button if you find this useful.