The Intersection Observer Literal

Creating a new Intersection Observer using constructor:

1
const observer = new IntersectionObserver(callback, options);
  • callback: The function to be called whenever the target enter/leave the intersection area.
  • options: An object that controls the condition of triggering the callback function.

options Object

The option object looks like this:

1
2
3
4
5
const option = {
root: null,
rootMargin: "0px",
thereshold: [0, 0.1]
}
  • root: the container for observation, by default is the viewport(null), but can also be other HTML elements.

  • rootMargin: a bit like css margin, controls the size of the root container(not actual size, but the size to detect intersection). The values can only be px.

    rootMargin: top, left, bottom, right

  • thereshold: the percentage of the observed items that triggers the callback function when entering the container.

    thereshold: 0.1 meaning trigger the callback function when 10% of the object first enter/leave the container.

callback function

The callback function by default has two parameters:

1
2
3
4
5
const callback = function(entries, observer){
entries.forEach(entry => {
console.log(entry);
})
}
  • entries: Since the observer can observe multiple elements at once, the state of each element will be put in the entries.

    • Each entry inside the entries is an object containing information about the observed element:

entry has many properties:

  • entry.target: the element being observed
  • entry.isIntersecting: whether the target is visible inside the root.
  • entry.intersectionRatio: visible ratio, behaves just like the thereshold
  • entry.boundingClientRect: the position of the element relative to the viewport
  • entry.time: time stamp when the callback function is triggered
  • observer: the IntersectionObserver itself
    • This is very useful cause we may want to stop the observation to avoid memory leakage:
      • observer.unobserve(entry.target): stop observing the element
      • observer.disconnect: stop observing every element in the observer
      • observer.observe(newElement): start observing the new element

Lazy load img with IntersectionObserver

1
<img src="blank-or-placeholder" data-src="real-url" alt=""/>

The img will not be loaded at first but will be blank or replaced. Using js, we could let the img to load only when the user start to see it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const lazyImg = document.querySelectorAll("img[data-src]")

const callback = function(entries, observer){
entries.forEach(entry => {
const img = entry.target;
// const realUrl = img.getAttribute("data-src");
// img.setAttribute("src", realUrl);
//the same effect
img.src = img.dataset.src;
// img.onload = () => {img.classList.add(.loading)};
//we can even add animation when img is loading
observer.unobserve(img);
})
}

const option = {
thereshold: 0.1,
root: null //by default it is already null
}

const lazyLoadObserver = new IntersectionObserver(callback, option);
lazyImg.forEach( img => {
lazyLoadObserver.observe(img);
})

The key point is to only load the img when the observer observed that the img is in the users’ view.