The Intersection Observer API
I want to know more about the Intersection Observer API. I currently use it for styling in the table of a contents for a page - which can be seen in the On This Page section in the right sidebar. I might use it in the future to load / unload content dynamically.
References
Notes
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.
Viewport
- A viewport represents a polygonal (normally rectangular) area in computer graphics that is currently being viewed. in web browser terms, it refers to the part of the document you're viewing which is currently visible in its window (or the screen, if the document is being viewed in full screen mode). Content outside the viewport is not visible onscreen until scrolled into view.
- The portion of the viewport that is currently visible is called the visual viewport. This can be smaller than the layout viewport, such as when the user has pinched-zoomed. The visual viewport is the visual portion of a screen excluding on-screen keyboards, areas outside of a pinch-zoom area, or any other on-screen artifact that doesn't scale with the dimensions of a page.
- The layout viewport is the viewport into which the browser draws a web page. Essentially, it represents what is available to be seen.
Introduction
- Historically, detecting 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 probe to causing application slowdown.
- Potential uses for the Intersection Observer:
- Lazy loading of content
- Implementing Infinite Scroll
- Advertisement visibility
- Deciding whether or not to perform tasks or animation processes based on whether or not the user will see the result
- The Intersection Observer API lets code register a callback function that is executed whenever a particular element enters or exits an intersection with another element (or the viewport), or when the intersection between two elements changes by a specific amount. This way, sites no longer need to do anything on the main thread to watch for this kind of element intersection, and the browser is free to optimize the management of intersections as it sees fit.
Concepts and Usage
- The Intersection Observer API allows you to configure a callback that is called when either:
- A target element intersects wither the device's viewport or a specified element. That specified element is called the root element or root for the purposes of the Intersection Observer API.
- The first time the observer is initially asked to watch a target element.
- Typically, you'll want to watch for intersection changes with regard to the target element's closest scrollable ancestor, or, if the target element isn't a descendant of a scrollable element, the device's viewport. To watch for intersection relative to the device's viewport, specify
null
for theroot
option. Keep reading for a more detailed explanation about intersection observer options. - Whether you're using the viewport or some other elements as the root, the API works the same way, executing a callback function you provide whenever the visibility of the target element changes so that it crosses desired amounts of intersections with the root.
- The degree of intersection between the target element and its root is the intersection ratio. This is a representation of the percentage of the target element which is visible as a value between 0.0 and 1.0.
Creating an Intersection Observer
- Create the intersection observer by calling its constructor and passing it a callback function to be run whenever a threshold is crossed in one direction or the other:
let options = {
root: document.querySelector('#scrollArea'),
rootMargin: "0px",
threshold: 1.0
};
let observer = new IntersectionObserver(callback,options);
- A threshold of 1.0 means that 100% of the target is visible within the element specified by the
root
option, the callback is invoked.
Intersection Observer Options
- The
options
object passed into theIntersectionObserver()
constructor lets you control the circumstances under which the observer's callback is invoked. root
- The element that is used as the viewport for checking visibility of the target. Must be the ancestor of the target. Defaults to the browser viewport if not specified or if
null
.
- The element that is used as the viewport for checking visibility of the target. Must be the ancestor of the target. Defaults to the browser viewport if not specified or if
rootMargin
- Margin around the root. Can have values similar to the CSS
margin
property (10xp 20px 30px 40px
). The values can be percentages. This set of values serves to grow or shrink each side of the root element's bounding vox before computing intersections.
- Margin around the root. Can have values similar to the CSS
threshold
- Either a single number or an array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed. If you only what to detect when visibility passes the 50% mark, you can use a value of 0.5. If you want the callback to run every time visibility passes another 25%, you would specify the array [0, 0.25, 0.5, 0.75, 1]. The default is 0 (meaning as soon as even one pixel is visible, the callback will be run). A value of 1.0 means that the threshold isn't considered passed until every pixel is visible.
Targeting an Element to be Observed
let callback = (entries, observer) => {
entries.forEach((entry) => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
}
let target = document.querySelector('#listItem');
observer.observe(target);
- The list of entries received by the callback includes one entry for each target which reported a change in its intersection status. Check the value of the
isIntersecting
property to see if the entry represents element that currently intersects with the root. - The callback is executed on the main thread.
How Intersection is Calculated
- All area considered by the Intersection Observer API are rectangles; elements which are irregularly shaped are considered as occupying the smallest rectangle which encloses all of the element's parts. Similarly, if the visible portion of an element is not rectangular, the element's intersection rectangle is considered to be the smallest rectangle that contains all the visible portions of the element.
The Intersection Root and Root Margin
- The container is the intersection root or root element. This can be either a specific element in the document which is an ancestor of the element to be observed, or
null
to use the document's viewport as the container. - The root intersection rectangle is the rectangle used to check against the target or targets. This rectangle is determined by:
- If the intersection root is the implicit root (that is, the top-level
Document
), the root intersection rectangle is the viewport's rectangle. - If the intersection root has an overflow clip, the root intersection rectangle is the root element's content area.
- Otherwise, the root intersection rectangle is the intersection root's bounding rectangle.
- If the intersection root is the implicit root (that is, the top-level
- The root intersection rectangle can be adjusted further by setting the root margin,
rootMargin
, when creating theIntersectionObserver
. The values inrootMargin
define the offsets added to each side of the intersection root's bounding box to create the final intersection root bounds.
Thresholds
- The intersection observer uses thresholds to report when a change has occurred. When you can create an observer, you can provide one or more numeric values representing percentages of the target element which are visible. The API only reports changes to visibility which cross these thresholds.
- If you want to be informed every time a target's visibility passes backward or forward each 25% mark, you would specify the array
[0, 0.25, 0.5, 0.75, 1]
as the list of threshold when creating the observer. - When the callback is invoked, it receives a list of
IntersectionObserverEntry
objects, one for each observed target which has had the degree to which it intersects the root change such that the amount exposed crosses over one of the threshold, in either direction. - You can see if the target currently intersects the root by looking at the entry's
isIntersecting
property; if the value istrue
, the target is at least partially intersecting the root element or document. This lets you determine whether the entry represents a transition from the elements intersecting to no longer intersecting a transition from not intersection to intersecting.
Intersection Change Callbacks
- When the amount of a target element which is visible within the root element crosses one of the visibility thresholds, the
IntersectionObserver
object's callback is executed. The callback receives as input an array of all ofIntersectionObserverEntry
objects, one for each threshold which was crossed, and a reference to theIntersectionObserver
object itself. - Each entry in the list of thresholds is an
IntersectionObserverEntry
object describing one threshold that was crossed; that is, each entry describes how much of a given element is intersecting with the root element, whether or not the element is considered to be intersecting or not, and the direction in which the transition occurred.
Interfaces
IntersectionObserver
- The primary interface for the Intersection Observer API. Provides methods for creating and managing an observer which can watch any number of target elements for the same intersection configuration. Each observer can asynchronously observe changes in the intersection between one or more target elements and a shared ancestor or with their top-level
Document
's viewport. The ancestor or viewport is referred to as the root. - When an
IntersectionObserver
is created, it's configured to watch for given ratios of visibility within the root. The configuration cannot be changed once theIntersectionObserver
is created, so a given observer object is only useful for watching for specific changes in degree of visibility; however, you can watch multiple target elements with the same observer. - Constructor:
IntersectionOberser()
- creates a newIntersectionObserver
object will execute a specified callback function when it detects that a target element's visibility has crossed one or more thresholds.
- The primary interface for the Intersection Observer API. Provides methods for creating and managing an observer which can watch any number of target elements for the same intersection configuration. Each observer can asynchronously observe changes in the intersection between one or more target elements and a shared ancestor or with their top-level
Instance Properties
IntersectionObserver.root
- The
Element
orDocument
whose bounds are used as the bounding box when testing for intersection. If notroot
value was passed to the constructor its value isnull
, the top-level document's viewport is used.
- The
IntersectionObserver.rootMargin
- An offset rectangle applied to the root's bounding box when calculating intersections, effectively shrinking or growing the root for calculation purposed. The value returned by this property may not be the same as the one specified when calling the constructor as it may be changed to match internal requirements.
IntersectionObserver.thresholds
- A list of thresholds, sorted in increasing numeric order, where each threshold is a ration of intersection area to bounding box area of an observed target. Notifications for a target are generated when any of the thresholds are crossed for that target. If no value was passed to the constructor, 0 is used.
Instance Methods
IntersectionObserver.disconnect()
- Stops the
IntersectionObserver
object from observing any target.
- Stops the
IntersectionObserver.observe(targetElement)
- Tells the
IntersectionObserver
a target element to observe. - The
targetElement
who visibility within the root is to be monitored. This element must be a descendant of the root element (or contained within the current document, if the root is the document's viewport).
- Tells the
IntersectionObserver.takeRecords()
- Returns an array of
IntersectionObserverEntry
objects for all observed targets.
- Returns an array of
IntersectionObserver.unobserve(target)
- Tells the
IntersectionObserver
to stop observing a particular target element. - The
target
is theElement
to cease observing. If the specified element isn't being observed, this methos does nothing and no exception is thrown.
- Tells the
IntersectionObserverEntry
- Describes the intersection between the target element and its root container at a specific moment of transition. Objects of this type can only be obtained in two ways: as an input to you
IntersectionObserver
callback, or by callingIntersectionObserver.takeRecords()
- Instances of
IntersectionObserverEntry
are delivered to anIntersectionObserver
callback in itsentries
parameter; otherwise, these objects can only be obtained by callingIntersectionObserver.rakeRecords()
- Describes the intersection between the target element and its root container at a specific moment of transition. Objects of this type can only be obtained in two ways: as an input to you
Instance Properties
IntersectionObserverEntry.boundingClientRect
- Returns the bounds rectangle of the target element as a
DomRectReadOnly
. The bounds are computed as described in the documentation forElement.getBoundingClientRect()
- Returns the bounds rectangle of the target element as a
IntersectionObserverEntry.intersectionRatio
- Returns the ratio of the
intersectionRect
to theboundingClientRect
- Returns the ratio of the
IntersectionObserverEntry.intersectionRect
- Returns a
DomRectReadOnly
representing the target's visible area
- Returns a
IntersectionObserverEntry.rootBounds
- Returns a
DomRectReadOnly
for the intersection observer's root
- Returns a
IntersectionObserverEntry.target
- The
Element
whose intersection with theroot
changed
- The
IntersectionObserverEntry.time
- A
DOMHighResTimeStamp
indicating the time at which the intersection was recorded, relative to theIntersectionObserver
's time origin
- A
Comments
There are currently no comments to show for this article.