function createStartStopScrollEvent(scrollContainer) { var scrollStart = new Event("scrollStart", {"bubbles":false}) var scrollStop = new Event("scrollStop", {"bubbles":false}) var timer = null; scrollContainer.addEventListener('scroll', function() { if(timer !== null) { clearTimeout(timer) } else { // Wait 50ms before emitting first scroll event. Because many scroll event handlers // wants a certain scroll distance treshold before doing something "clever" like // hiding or showing a shadow or menu. window.setTimeout(function() { scrollContainer.dispatchEvent(scrollStart) }, 50) } timer = setTimeout(function() { scrollContainer.dispatchEvent(scrollStop) timer = null }, 50) }) } var scrollContainer = document.querySelector('.scrollContainer') var message = document.querySelector('.message') createStartStopScrollEvent(scrollContainer) scrollContainer.addEventListener('scrollStart', function() { message.textContent = 'Scroll startet' }) scrollContainer.addEventListener('scrollStop', function() { message.textContent = 'Scroll stopped' })
<div class="scrollContainer"> This contains a lot of content! </div> <div class="message"> </div>
/** We had a lot of performance issues with scroll event handlers. I tried resolve this with debounce and/or throttle, but was not satisfied with the result (having to wait 250ms before screen updatet). My first try of resolving this involved a combination of debounce and throttle. You can see this here: https://jsfiddle.net/lebbe/eygq4m4b/ After a while, I realised I only needed to update GUI on scroll start and scroll stop (updating shadow drops in a material design themed web application). There aren't any scroll start and scroll stop events in the browser, but I mimick it with this code. If you want something "animated" with the scroll, you can of course not use scroll start or stop events. But these events will cover lots of cases none the less. If, for example, you are toggling on (showing) some elements that should follow the scroll, they can be be "positioned: fixed", etc. **/ .scrollContainer { white-space: pre; height: 70px; overflow: auto; }