(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; }