Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IntersectionObserver: how rootMargin work?

I want intercep an intersection when the target element is at 100px from the intersection root

enter image description here

for make it, i have setted rootMargin with '100px 0px 100px 0px'.

In this example the intersection become when the first pixel of target element (red box) enter into the intersetion root

enter image description here

i want the intersetion become when the target element is at 100px from the intersection root (grey area)

    var io = new IntersectionObserver(function(entries){
      document.getElementById('info').innerHTML =  entries[0].isIntersecting ? 'isIntersecting = true' : 'isIntersecting = false'; 
    }, {
      rootMargin: '100px 0px 100px 0px'
    });
    io.observe(document.getElementById('target'));
* {
  padding: 0;
  margin: 0;
}

.pad {
  height: 1000px;
}

#target {
  background: rgb(237, 28, 36);
  height: 100px;
  outline: 100px solid rgba(0,0,0,0.2);
}

#info {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 2rem;
}
<div class="pad"></div>
<div id="target"></div>
<div class="pad"></div>
<span id="info">isIntersecting = true</span>
like image 602
ar099968 Avatar asked Oct 30 '19 09:10

ar099968


1 Answers

By default the root is a document viewport which is not direct ancestor of #target element.
To make it work you must specify the root element.
According to specification:

Note: rootMargin only applies to the intersection root itself. If a target Element is clipped by an ancestor other than the intersection root, that clipping is unaffected by rootMargin.

var io = new IntersectionObserver(function(entries) {
  document.getElementById('info').innerHTML = entries[0].isIntersecting ? 'isIntersecting = true' : 'isIntersecting = false';
}, {
  root: document.querySelector('.container'),
  rootMargin: '100px 0px 100px 0px'
});
io.observe(document.getElementById('target'));
* {
  padding: 0;
  margin: 0;
}

.container {
  max-height: 300px;
  overflow-y: scroll;
}

.pad {
  height: 1000px;
}

#target {
  background: rgb(237, 28, 36);
  height: 100px;
  outline: 100px solid rgba(0, 0, 0, 0.2);
}

#info {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 2rem;
}
<div class="container">
  <div class="pad"></div>
  <div id="target"></div>
  <div class="pad"></div>
</div>
<span id="info">isIntersecting = true</span>

Check this fiddle

like image 71
Artem Bozhko Avatar answered Sep 18 '22 11:09

Artem Bozhko