I have a main layout block with the property overflow: auto
and because of this, the scroll event is triggered only in this block, although I add a listener to the window object.
How do I add a scroll event listener to the window if I don't know the class or id of the specific block on which the event occurs?
window.addEventListener('scroll', () => {
console.log('scroll!')
});
* {
margin: 0;
padding: 0;
}
main {
height: 100vh;
overflow-y: auto;
}
div {
width: 500px;
height: 300px;
margin: 10px 0;
background: rgb(45, 62, 206);
}
<main>
<div></div>
<div></div>
<div></div>
<div></div>
</main>
I'm with Rory, this seems like it could be an X/Y problem. But answering the question asked:
scroll
events don't bubble, but you can still handle them on ancestor elements by adding a listener for the capture phase (true
as a third argument to addEventListener
). The capture phase occurs even for events that don't bubble:
window.addEventListener('scroll', () => {
console.log('scroll!')
}, true); // <===
Live Example:
window.addEventListener('scroll', () => {
console.log('scroll!')
}, true);
* {
margin: 0;
padding: 0;
}
main {
height: 100vh;
overflow-y: auto;
}
main div {
width: 500px;
height: 300px;
margin: 10px 0;
background: rgb(45, 62, 206);
}
<main>
<div></div>
<div></div>
<div></div>
<div></div>
</main>
This diagram from the DOM UI Events specification is helpful for understanding capture vs. target vs. bubbling phases:
In events that don't bubble, it's just the bubbling phase, not the capture phase, that doesn't happen.
(In the runnable example I made a small change to the CSS that's unrelated to the answer; it's just so the Stack Snippet works better. The Stack Snippet console is a div inside the document, so it was being affected by your div
rule. I just changed the rule's selector to be main div
instead so it only applied to the elements within main
.)