Why could window scroll event not being fired
Asked Answered
Q

4

8

I have this js class:

export class ScrollBehaviorComponent {
  init() {
    const body = document.querySelector('body')
    let previousScroll = window.pageYOffset || 0
    let scrollDirIsUp = false

    window.addEventListener('scroll', function(e) {
      const currentScroll = window.pageYOffset // never gets updated
      scrollDirIsUp = currentScroll > 0 && previousScroll >= currentScroll // never gets updated
      body.classList.toggle('body--scroll-up', scrollDirIsUp) // never gets updated

      alert('scroll is up: ', window.pageYOffset) // never happens
    })

    console.log(window) // I see this log, o_0
  }
}

export default ScrollBehaviorComponent

That I used already before but for this one specific project the event is not fired.

I load it like this:

import ScrollBehaviorComponent from 'Shared/scroll-behavior/scroll-behavior.component'

export const HomeModule = {
  init() {
    new ScrollBehaviorComponent().init()

    // rest of page's code..
  },
}

The problem is that even that the developer's console fires no error, the event is also never fired.

Not even if I input in the developers console (and again, no errors)

window.window.addEventListener('scroll', function(e) {
  console.log('scroll is up: ', window.pageYOffset) // never happens
})

Which is fired in stackoverflow as I'm typing.

enter image description here

What could it be the reason? somewhere in the app is stopping event propagation? If so, any clue how to find it? other guess? ( its an inherited project )

Quidnunc answered 14/7, 2020 at 21:39 Comment(1)
As someone mentioned it might be due to the wrong context of the scroll, maybe you scroll on a different element and listen on the window. Maybe you can try new Intersection Observable API (link). I think it works better than window scroll event. But it is just a small hint.Ehtelehud
E
20

It could be that some element (the body itself or some nested div) has the css overflow property set to scroll.

To try to identify which is you could add something like:

document.querySelectorAll("*").forEach(
  element => element.addEventListener("scroll",
    ({target}) => console.log(target, target.id, target.parent, target.parent.id)
  )
);

just be sure to run it when the page is full rendered; then in your console you should have quite enough data to identify which element is scrolling.

Elfin answered 29/7, 2020 at 10:31 Comment(4)
Even that i had to change getElementsByTagName for querySelectorAll and foreach by forEach it helped figuring out ;) Very much appreciatedQuidnunc
Hi @ToniMichelCaubet , if this actually helped to solve the problem, could I ask to kindly accept the answer before the bounty expires?Elfin
I would rather wait a litter longer. Also, I would suggest you edit your answer with the fixes i mentioned (your code does not work)Quidnunc
This answer helped someone after 2 years as well. Thankyou @DanieleRicciSplore
D
5

The window can't be scrolling without emitting scroll events. You can verify that some third party code has not removed the event listener by clicking the <!DOCTYPE html> element in developer tools (you could also run getEventListeners(window).scroll):

enter image description here

If you see the event listener, then in your app you are actually scrolling another element:

Example of full page window scroll:

window.addEventListener('scroll', function() {
  console.log('Scroll event');
});
#big-content {
    height: 1000px;
}
<div id="big-content">
</div>

Example where you could believe you are scrolling the window but you are actually scrolling a full-page underlying element:

window.addEventListener('scroll', function(e) {
  console.log('Underlying element scroll event bubbled'); // never happens
});

document.getElementById('container').addEventListener('scroll', function({ bubbles }) {
    console.log('Will bubble: ', bubbles);
});
#container {
    position: fixed;
    height: 100vh;
    width: 100vw;
    overflow: scroll;
}

#big-content {
    height: 1000px;
}
<div id="container">
    <div id="big-content">
    </div>
</div>

In that case, the event doesn't bubble and you can't listen to it at window level.

Devoe answered 30/7, 2020 at 13:24 Comment(0)
S
4

That's probably because the element scrolling is not the body. Take as example this snippet. I am binding the scrolling to the body, but since the element scrolling is the and not the body, the element won't be triggered. You should check out your style and your dom.

document.body.addEventListener('scroll', () => {
  console.log('Hi')
  const elem = document.createElement('div');
  elem.innerText = 'Hi';
  document.body.appendChild(elem);
});
<html>
  <body>
    <main style="height: 3000px">
      <div>Hello</div>
      <div>This</div>
      <div>Is</div>
      <div>A</div>
      <div>Test</div>
    </main>
  </body>
</html>
Stapler answered 3/8, 2020 at 20:51 Comment(1)
In my case it was something related to the body. Since there was the body with a 100% heightCandra
E
1

i faced this problem during last project you need to fill the quotation of html the solution is

   import HomeModule from "./home";
    HomeModule.init();
    document.getElementById("app").innerHTML = `<div class="page__inner"><main class="main main_width-limit"><header class="main__header"><div class="main__header-inner"><div class="main__header-group"><ol class="breadcrumbs"><li class="breadcrumbs__item breadcrumbs__item_home"><a class="breadcrumbs__link" href="/"><span class="breadcrumbs__hidden-text">Tutorial</span></a></li><li class="breadcrumbs__item" id="breadcrumb-1"><a class="breadcrumbs__link" href="/ui"><span>Browser: Document, Events, Interfaces</span></a></li><li class="breadcrumbs__item" id="breadcrumb-2"><a class="breadcrumbs__link" href="/event-details"><span>UI Events</span></a></li><script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Tutorial","item":"https://javascript.info/"},{"@type":"ListItem","position":2,"name":"Browser: Document, Events, Interfaces","item":"https://javascript.info/ui"},{"@type":"ListItem","position":3,"name":"UI Events","item":"https://javascript.info/event-details"}]}</script></ol><div class="updated-at" data-tooltip="Last updated at 2nd December 2019"><div class="updated-at__content">2nd December 2019</div></div></div><h1 class="main__header-title">Scrolling</h1></div></header><div class="content"><article class="formatted" itemscope="" itemtype="http://schema.org/TechArticle"><meta itemprop="name" content="Scrolling"><div itemprop="author" itemscope="" itemtype="http://schema.org/Person"><meta itemprop="email" content="[email protected]"><meta itemprop="name" content="Ilya Kantor"></div><div itemprop="articleBody"><p>The <code>scroll</code> event allows to react on a page or element scrolling. There are quite a few good things we can do here.</p>
<p>For instance:</p>
<ul>
<li>Show/hide additional controls or information depending on where in the document the user is.</li>
<li>Load more data when the user scrolls down till the end of the page.</li>
</ul>
<p>Here’s a small function to show the current scroll:</p>
<div data-trusted="1" class="code-example" data-autorun="true" data-prism-highlighted="1">
      <div class="codebox code-example__codebox">
        
        <div class="codebox__code" data-code="1">
          <pre class="line-numbers  language-javascript"><code class=" language-javascript">window<code class="token punctuation">.</code><code class="token function">addEventListener</code><code class="token punctuation">(</code><code class="token string">'scroll'</code><code class="token punctuation">,</code> <code class="token keyword">function</code><code class="token punctuation">(</code><code class="token punctuation">)</code> <code class="token punctuation">{</code>
  document<code class="token punctuation">.</code><code class="token function">getElementById</code><code class="token punctuation">(</code><code class="token string">'showScroll'</code><code class="token punctuation">)</code><code class="token punctuation">.</code>innerHTML <code class="token operator">=</code> window<code class="token punctuation">.</code>pageYOffset <code class="token operator">+</code> <code class="token string">'px'</code><code class="token punctuation">;</code>
<code class="token punctuation">}</code><code class="token punctuation">)</code><code class="token punctuation">;</code></code><span class="line-numbers-rows"><span></span><span></span><span></span></span></pre>
        </div>
      </div>
      
      </div><p>In action:</p>
<p>Current scroll = <b id="showScroll">43.20000076293945px</b></p>
<p>The <code>scroll</code> event works both on the <code>window</code> and on scrollable elements.</p>
<h2><a class="main__anchor" name="prevent-scrolling" href="#prevent-scrolling">Prevent scrolling</a></h2><p>How do we make something unscrollable?</p>
<p>We can’t prevent scrolling by using <code>event.preventDefault()</code> in <code>onscroll</code> listener, because it triggers <em>after</em> the scroll has already happened.</p>
<p>But we can prevent scrolling by <code>event.preventDefault()</code> on an event that causes the scroll, for instance <code>keydown</code> event for <kbd class="shortcut">pageUp</kbd> and <kbd class="shortcut">pageDown</kbd>.</p>
<p>If we add an event handler to these events and <code>event.preventDefault()</code> in it, then the scroll won’t start.</p>
<p>There are many ways to initiate a scroll, so it’s more reliable to use CSS, <code>overflow</code> property.</p>
<p>Here are few tasks that you can solve or look through to see the applications on <code>onscroll</code>.</p>
</div></article><div class="tasks formatted"><h2 class="tasks__title" id="tasks"><a class="tasks__title-anchor main__anchor main__anchor main__anchor_noicon" href="#tasks">Tasks</a></h2><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#endless-page" name="endless-page">Endless page</a></h3><a class="task__open-link" href="/task/endless-page" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 5</span></div><div class="task__content"><p>Create an endless page. When a visitor scrolls it to the end, it auto-appends current date-time to the text (so that a visitor can scroll more).</p>
<p>Like this:</p>`

it is work correctly

the result of scrolling

Elnoraelnore answered 5/8, 2020 at 12:7 Comment(1)
I don't think it's same problem (also your code is crashing due import outside a module.. )Quidnunc

© 2022 - 2024 — McMap. All rights reserved.