Edit in JSFiddle

(function(parent, event) {
  const observer = new IntersectionObserver((entries) => {
    event.innerHTML = '';
    entries
      .filter(entry => entry.isIntersecting)
      .forEach(entry => event.innerHTML = (entry.target.id + ': ' + entry.intersectionRatio));
  }, {
    root: parent,
    threshold: new Array(101).fill(0).map((zero, index) => {
      return index * 0.01;
    })
  });

  for (const position of['Above', 'Giant', 'Below']) {
    const child = document.createElement('div');
    child.id = position;
    child.innerHTML = position;
    parent.appendChild(child);

    observer.observe(child);
  }
})(document.getElementById('parent'), document.getElementById('event'));
<div class="wrapper">
  <div id="parent"></div>
</div>
<div id="event"></div>
body {
  overflow-y: hidden;
}
.wrapper {
  background:#E7ECF5;
  border: 2px solid #02E4FF;
  padding: 2em;
}

#parent {
  height: 350px;
  overflow-y: scroll;
}

#event {
  position: absolute;
  top: 20px;
  right: 20px;
  background: #465466;
  border-radius: 4px;
  box-shadow: 0px 2px 28px 0px rgba(0,0,0,0.25);
  color: white;
  padding: 1em;
}

#Above,
#Below,
#Giant {
  background: #fff;
  border: 1px solid #F6A6FF;
  height: 20vh;
  margin-bottom: 1em;
  padding: 0.5em;
}

#Giant {
  height: 300vh;
}