JS API Intersection Observer and lazy loading

Mapbox recently released Global View, which can run smoothly and smoothly on both Web and Mobile.

Mapbox

So I changed the map on my blog at the first time. Since this map is not on the first screen on my blog, considering the feelings of some mobile users, I decided to lazy load it, that is initialize the earth when the page scrolls to its position.

This problem has successfully become the lazy loading problem we often encounter. The traditional method is to listen to the scroll event, and then use a method similar to getBoundingClientRect() to obtain the coordinates of the object, and then perform various calculations to determine Whether the target element is present in the viewport. But because scroll is triggered frequently, and the execution of getBoundingClientRect()is also running on the main thread of the browser, it is prone to performance problems and is not so elegant. In this case our protagonist Intersection Observer API shines!

1. What is Intersection Observer API

Intersection Observer API is relatively concise and easy to understand,it consists of 2 parts observer and observed element. After specifying the relationship between the observer and the observed element, the observer will pay close attention to the observed element and call a callback function when certain conditions are met (configured through the observersoptions`).

1.1 IntersectionObserver

We can initialize an Observer with new IntersectionObserver(callback, options), for example:

// initialize
let options = {
  root: document.querySelector('#box'),
  rootMargin: '0px',
  threshold: 1.0
}

const observer = new IntersectionObserver(callback, options);

// monitor element
const el = document.querySelector('#target') // element being monitored
observer.observe(el) // start listening for elements

1.1.1 options

options are configuration parameters that mainly tell the observer when the callback should be triggered:

  • root is the observer element, must be the parent element of the observed element, if not specified, it defaults to the browser window.
  • rootMargin is similar to CSS margin, can be set to a value such as 10px, 10px 20px 10px 20px, default is 0
  • threshold is used to control how far the observed element intersects the observer's viewport to trigger the callback. It can be a number between 0-1, or an array of numbers between 0-1, such as [0.1,0.5,1.0]. For details, please refer to the elevator example below.

To start our elevator example, the elevator door of a certain floor (corresponding to the root in options) is equivalent to an observer, and the elevator box is equivalent to an observed element. As a elevator developer, we can make the elevator run according to our needs. For example, when the elevator just reaches this floor (rootMargin), the bell will ring to remind the waiting users, and when the elevator completely reaches the floor (threshold), turn on the elevator door.

Figure 1: Example of root and rootMargin

root & rootMargin

Figure 2: For an upward elevator, when the top reaches the bottom of the elevator door(Include the margin), the threshold is 0 (the elevator door must not be opened at this time, otherwise...), when the elevator completely overlaps the elevator door, the threshold is 1 (The elevator door can now be opened with confidence... ahem, right? Seems we missed the margin)

threshold

Figure 3: If threshold is an array, a callback will be triggered when any value satisfies the condition

threshold

1.1.2 callback

The callback method will be triggered when:

  1. The observed enters or leaves the viewport.
  2. When the Observed Element is bound, please pay special attention to this trigger when the initial binding is performed, and check whether the Observed element is in the viewport or not through IntersectionObserverEntry.isIntersecting.

The callback method accepts 2 parameters entries and observer:

  1. entries is a collection of instances of related observed elements (IntersectionObserverEntry)
  2. observer is an instance of Observer (IntersectionObserver)

1.1.3 IntersectionObserverEntry

IntersectionObserverEntry (the Observed Element instance) contains the following read-only properties:

  • boundingClientRect: Returns DOMRectReadOnly. As same as Element.getBoundingClientRect().
  • intersectionRatio:Returns the ratio of intersectionRect and boundingClientRect.
  • intersectionRect: Returns a [DOMRectReadOnly describing the intersection area of ​​the root and target elements.
  • isIntersecting:Returns a boolean value that returns true if the target element intersects the root of the intersection observer object. If it returns true, the IntersectionObserverEntry describes the state of the transition to the intersection; if it returns false, Then it can be judged from this that the transition is from a cross state to a non-cross state.
  • rootBounds: Returns a DOMRectReadOnly describing the root in the intersection observer.
  • target: The element (Element) that changes the area of ​​intersection with the root.
  • time: Returns a timestamp from the origin of the IntersectionObserver to the time the intersection was triggered.

1.1.3 IntersectionObserverEntry

IntersectionObserverEntry (an observer instance) contains the following read-only properties: root, rootMargin, thresholds, and the following methods:

  • .disconnect(): stop listening work
  • .observer(targetElement): start listening to an element
  • .takeRecords(): returns a list of all observed objects
  • .unobserve(target): stop listening to a specific target

2. Typical application scenarios of Intersection Observer

2.1 Lazy loading of images

This may be one of the most common application scenarios. The specific process can be: by creating the page viewport as an observer object ➡️ Binding all image placeholders in the page ➡️ After the observer callback is triggered ➡️ Traversal Matched objects ➡️ Use isIntersecting judgment to replace the placeholder with the actual image. I won't go into too much detail here.

2.2 Scroll to the bottom of the page with autoload function

We often see the automatic loading dynamic function of scrolling to the bottom of the page, which can also be cleverly implemented by Intersection Observer: place an observed element similar to load more at the bottom of the page. When this element appears in the field of view, Call the API to get more data to fill in.

I wrote a simple Demo:

Demo传送门

3. Bonus

While consulting related materials, I found some good demos or documents and shared them with you:

3.1. Example of Intersection Observer API Principle

Find a good example in codepen to fully understand the relevant parameters of the Intersection Observer API in an interactive way

Demo link

Demo Author https://codepen.io/michellebarker

3.2. How to use it in React - "Lazy Loading Images in React"

If you are using React, here is a good article on Lazy Loading Using the Intersection Observer API with React, keywords useEffect, useRef

Link

45850
  • logo
    • HI, THERE!I AM MOFEI

      (C) 2010-2024 Code & Design by Mofei

      Powered by Dufing (2010-2020) & Express

      IPC证:沪ICP备2022019571号-1