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.

Date Created:
Last Edited:

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 the root 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 the IntersectionObserver() 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.
    • 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.
    • 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.
  • The root intersection rectangle can be adjusted further by setting the root margin, rootMargin, when creating the IntersectionObserver. The values in rootMargin 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 is true, 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 of IntersectionObserverEntry objects, one for each threshold which was crossed, and a reference to the IntersectionObserver 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 the IntersectionObserver 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 new IntersectionObserver object will execute a specified callback function when it detects that a target element's visibility has crossed one or more thresholds.
Instance Properties
  • IntersectionObserver.root
    • The Element or Document whose bounds are used as the bounding box when testing for intersection. If not root value was passed to the constructor its value is null, the top-level document's viewport is used.
  • 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.
  • 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).
  • IntersectionObserver.takeRecords()
    • Returns an array of IntersectionObserverEntry objects for all observed targets.
  • IntersectionObserver.unobserve(target)
    • Tells the IntersectionObserver to stop observing a particular target element.
    • The target is the Element to cease observing. If the specified element isn't being observed, this methos does nothing and no exception is thrown.


  • 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 calling IntersectionObserver.takeRecords()
    • Instances of IntersectionObserverEntry are delivered to an IntersectionObserver callback in its entries parameter; otherwise, these objects can only be obtained by calling IntersectionObserver.rakeRecords()
Instance Properties
  • IntersectionObserverEntry.boundingClientRect
    • Returns the bounds rectangle of the target element as a DomRectReadOnly. The bounds are computed as described in the documentation for Element.getBoundingClientRect()
  • IntersectionObserverEntry.intersectionRatio
    • Returns the ratio of the intersectionRect to the boundingClientRect
  • IntersectionObserverEntry.intersectionRect
    • Returns a DomRectReadOnly representing the target's visible area
  • IntersectionObserverEntry.rootBounds
    • Returns a DomRectReadOnly for the intersection observer's root
  • IntersectionObserverEntry.target
    • The Element whose intersection with the root changed
  • IntersectionObserverEntry.time
    • A DOMHighResTimeStamp indicating the time at which the intersection was recorded, relative to the IntersectionObserver's time origin

Comments

You must be logged in to post a comment!

Insert Math Markup

ESC
About Inserting Math Content
Display Style:

Embed News Content

ESC
About Embedding News Content

Embed Youtube Video

ESC
Embedding Youtube Videos

Embed TikTok Video

ESC
Embedding TikTok Videos

Embed X Post

ESC
Embedding X Posts

Embed Instagram Post

ESC
Embedding Instagram Posts

Insert Details Element

ESC

Example Output:

Summary Title
You will be able to insert content here after confirming the title of the <details> element.

Insert Table

ESC
Customization
Align:
Preview:

Insert Horizontal Rule

#000000

Preview:


Insert Chart

ESC

View Content At Different Sizes

ESC

Edit Style of Block Nodes

ESC

Edit the background color, default text color, margin, padding, and border of block nodes. Editable block nodes include paragraphs, headers, and lists.

#ffffff
#000000

Edit Selected Cells

Change the background color, vertical align, and borders of the cells in the current selection.

#ffffff
Vertical Align:
Border
#000000
Border Style:

Edit Table

ESC
Customization:
Align:

Upload Lexical State

ESC

Upload a .lexical file. If the file type matches the type of the current editor, then a preview will be shown below the file input.

Upload 3D Object

ESC

Upload Jupyter Notebook

ESC

Upload a Jupyter notebook and embed the resulting HTML in the text editor.

Insert Custom HTML

ESC

Edit Image Background Color

ESC
#ffffff

Insert Columns Layout

ESC
Column Type:

Select Code Language

ESC
Select Coding Language