Intersection observer API instead of the scroll event

Is it possible that we can know or calculate the percentage of page scrolled with the help of intersection observer API instead of the scroll event?

I think that the answer will be yes, If that’s right then can someone please help me with which property should I explore to get through?

image

I think you can only detect when an element intersects with the target element (or viewport) but you can specify a percentage of the element that needs to be visible before the code is triggered.

What is is that you want to do exactly?

I used it here to add color to a sticky header once it was sticky,

1 Like

Sir, when 30% scroll bar, for example, of the total available viewport height is scrolled I want to do something then.

You could place the observer 30% from the top of the page and then once it intersects the viewport top you can add a class to do something somewhere :slight_smile:

Roughly like this:

(But then I’m no expert ;))

2 Likes

Sir, where is it’s HTML?

image

Got it:

body:after{
  content:"Scrolled 30%";
1 Like

I just used the pseudo element on the body to show the message.

body:after{
  content:"Scrolled 30%";
  position:fixed;
  width:200px;
  height:200px;
  display:flex;
  text-align:center;
  justify-content:center;
  align-items:center;
  border:5px solid #000;
  left:0;
  right:0;
  bottom:0;
  top:0;
  margin:auto;
  box-shadow:0 0 20px 20px rgba(0,0,0,0.5);
  background:red;
  font-size:1.5rem;
  opacity:0;
  transition:.5s ease;
}
body.active:after{
  opacity:1;
}

You can use a real element if you want.

Is that what you meant?

1 Like

Sir, I read your code could not get the logic of how you are calculating the 30% scrollbar is scrolled? Can you please guide me with the logic?

The Js creates an element which I’ve called myObserver and I’ve placed it in relation to the body at 30% from the top of the viewport. It may help if you make the element visible because at the moment its hidden as its not used for anything other than observing. I’ve added some more height and width so you can now see it at 30% from the top of the page.

/* this element added by JS to act as the observer*/
.myObserver {
  height: 10px;
  width: 200px;
  pointer-events: none;
  position: absolute;
  top:30%;
  z-index: -1;
  overflow: hidden;
  background:green
}

You can see the element in green in the screenshot above at 30% from the top of the viewport.

As you scroll the page the element moves up as shown in the screenshot below.

When finally the element passes the top of the viewport that means we must have scrolled 30% because that’s where we originally placed it and then the observer gets triggered and the red box shows.

Does that makes sense :slight_smile:

1 Like

wow, very intelligent programming. I was unable to interpret it on my own.

Is there a way we can change it through JS also? Changing it through CSS is simple, but is there a way around if we can change it through JS?

Scroll bar position: 30%, for example, will be needed to do something else. In real situations, there is no need to show this DIV. but even if we use display:none then it will not be treated as intersected by Intersection observer API.

The observer div is already hidden in my original code as it is only 1px x 1px and has no effect on the page content at all due to the negative z-index and the pointer-events:none;. There is no need for display:none to hide it; it’s already invisible. You can just forget about it.

Yes you can do it in JS if you need to by setting the top:position of the style object.

e.g.In my example

newEl.style.top = “80%”;

1 Like

Sir, If we set opacity: 0 then also we can make it invisible, Right? This may be another way to make it invisible?

This is very useful when we may build something of any commercial utility and this 30% of 80% or any other x% is based on what value the administrator of the website has chosen in the admin option this can be easily customized.

Yes opacity:0 can make elements transparent but is not needed in my demo because the element is already transparent and has no content.

If you are talking about other cases perhaps then you can use opacity to hide things but you still need pointer-events to avoid the element blocking something else. You would also need to ensure the element takes up no space so hiding with clip may be better. It all depends on your use case.

For the observer though we want it to be 1px x 1px so we can observe it properly. It causes no harm and just scrolls up and down and triggers the routine on intersection.

1 Like

That is because z-index is set to a negative number.

That was just a fall back if pointer events was not supported. Pointer events is the key :slight_smile:

1 Like

Sir viewport height is not the same as the total height available for the scroll. The scrolling height will change based on the content available.

So, the idea will not work. Code on codepen:

On local machine:

codepen__

can’t we fix the hack div based on the maximum available height to scroll, not viewport 30%?

Full-width view of the GIF

That’s not what you asked for?

You asked for 30% of the viewport height. You didn’t ask for 30% of the content height which is completely different thing.:slight_smile:

I’m sure there is an easier way of doing this so one of the JS gurus may have to jump in but I made the observer element 30% of the height of the content (using position:relative on the content and appending the observer to the content and placed absolutely).

Change the width of the myObserver element to 100px and its background to green to see how it works.

I’m sure there is a more elegant way but it seems to work.:slight_smile:

2 Likes

Yes, right. My bad I didn’t put it correctly.

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