Brad Woods Digital Garden

Notes / JavaScript / Web API / Intersection Observer

The Warhammer 40k Adeptus Mechanicus symbol

Table of contents

    A grid of squares. The middle ones highlighted.

    Intersection Observer

    Planted: 

    Tended: 

    Status: mature

    Hits: 1760

    Intended Audience: Front-end developers

    The Intersection Observer is a Web API that fires a callback when a target element starts (or stops) intersecting the viewport (or specified element).

    Options

    IntersectionObserver can take an options object with three properties:

    /index.js

    const options = {
    root: null,
    rootMargin: "0%",
    threshold: 0,
    }
    const observer = new IntersectionObserver(() => {}, options)

    root

    Can be set to:

    • the viewport (by ommiting or setting to null) or
    • an ancestor element of the target.

    rootMargin

    Sets the root's intersection area size. By default, it's 100% of the viewport. It accepts values similar to the CSS margin property in pixels or percentages. If set to -50% 0, the area will be a 1px line in the middle of the viewport.

    /index.js

    const options = {
    rootMargin: "0% 0%"
    }
    Is intersecting: false

    threshold

    Sets how much of the target needs to overlap the intersection area to fire the callback. A value between 0 (0%) and 1 (100%). A value of 0 will fire the callback when 1px of the target overlaps. It can also be set to an array. Example: [0.2, 0.4, 0.6, 0.8]

    /index.js

    const options = {
    rootMargin: "-25% 0%",
    threshold: 0.2
    }
    Is intersecting: false

    Callback

    The callback is executed when:

    • when a target is initially passed to the observer, observer.observe(target) and
    • when a target starts (or stops) intersecting the root.

    It takes two arguments:

    /index.js

    const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
    const {
    boundingClientRect,
    intersectionRatio,
    intersectionRect,
    isIntersecting,
    rootBounds,
    target,
    time
    } = entry
    ...
    })
    })

    Unobserve

    /index.js

    // to stop observing a target
    observer.unobserve(target)
    // to stop observing all targets
    observer.disconnect()

    Performance

    The callback is executed on the main thread. This means if the code in the callback requires a lot of system resources, it could degrade UX (User Experience) by blocking the browser. If this is the case, consider using requestIdleCallback.

    Use cases

    • Dynamic Header
    • Infinite Scroll
    • Table of Contents
    • Lazy-load content when scrolled into view
    • Start / stop animations entering / leaving the viewport
    • Reporting visibility of advertisements to calculate ad revenues
    • Drag and Drop

    Feedback

    Have any feedback about this note or just want to comment on the state of the economy?

    Where to next?