Intersection observer discussing lots of examples

Hi there,

The full source code is available here.

I am facing difficulty understanding this →

// Next we want to create a function that will be called when that element is intersected
function handleIntersection(entries) {
  // The callback will return an array of entries, even if you are only observing a single item
  entries.map((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add('visible')
    } else {
      entry.target.classList.remove('visible')
    }
  });
}

The JS map function creates a new array →

What is entry here?

entry is the iterated item of the entries array.

map is essentially:

var outarray;
inarray.forEach((x) => {
   ....do stuff to x here;
  outarray.push(x);
}
return outarray;

in one command.

(there’s some nuance, like the fact that x doesnt need to be anything like it started out as at the end, but in broad terms)

1 Like

Thanks, I understand your interpretation, but could not connect that to my example posted.

  entries.map((entry) => {
   ...do stuff to entry here
  });

In truth, your example (being that it doesnt actually return a value, it’s manipulating DOM elements) should probably be a forEach, rather than a map.

The idea of the map is to take an input array, and return a different array with manipulated values for each element.

What your code is tryhing to do is to use the elements of the array to change some aspect of their linked DOM elements. Different use case.

1 Like

That is not my code. I was trying to understand the intersection observer. Can you write that whole code in a better, precise, and more logical way?

For this specific case?

function handleIntersection(entries) {
    entries[0].target.classList.toggle('visible',entries[0].isIntersecting);
}

For a generic case of ‘there may be many elements’?

function handleIntersection(entries) {
    entries.forEach((entry) => entry.target.classList.toggle('visible',entry.isIntersecting););
}
1 Like

So there is no necessity for a map function? Any more? This will be the final full code →

const target = document.querySelector('.animated-text');
function handleIntersection(entries) {
entries.forEach((entry) => entry.target.classList.toggle('visible',entry.isIntersecting););
}
const observer = new IntersectionObserver(handleIntersection);
observer.observe(target);

Weare picking the part of the HTML that needs to be animated.

This is the callback function, which does the DOM manipulation.

This is the new observer created.

This renders the final output, which is desired. Althoug I understand the causation inside the code, but still have some difficulty in analysing the last part of the code. Thank you so much.

No, this scopes the observer to tell it to watch for its specific type (intersection) in relation to the target.
When it has an observation to report, it calls the handler (handleIntersection in this case) to deal with whatever it has observed.

It is the handler that actually causes the object to animate by nature of applying a class to the element, which causes a CSS animation to play out (as defined by the CSS of the demo).

1 Like

So how are the two connected in the code here? Are target and Intersection not the same? Any way console can used to visualize this?

I think that a useful way to think of the IntersectionObserver is that it behaves similar to an event handler, such as the mouseEnter or mouseLeave event. In the case of intersections, it’s triggering an event when the element enters or leaves the screen.

1 Like

Thank you so much. There is a constant pattern in using this API.

Two steps:

  1. const observer = new IntersectionObserver();
  2. observer.observe(section);

The first one creates a new object from that API, and if my understanding is correct then
the 2nd one gives the instruction to that object that which part of the DOM to intersect/monitor/implement change, in terms of visibility of that element.

There is one more example here →

This part →

const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
	const id = entry.target.getAttribute('id');
	if (entry.intersectionRatio > 0) {
		document.querySelector(`nav li a[href="#${id}"]`).parentElement.classList.add('active');
	} else {
		document.querySelector(`nav li a[href="#${id}"]`).parentElement.classList.remove('active');
	}
});
});

And this is #2:

// Track all sections that have an `id` applied
document.querySelectorAll('section[id]').forEach((section) => {
	observer.observe(section);
});

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.