Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why could window scroll event not being fired

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 )

like image 546
Toni Michel Caubet Avatar asked Jul 14 '20 21:07

Toni Michel Caubet


People also ask

How do I listen to scroll event in react?

To handle the onScroll event in React: Set the onScroll prop on an element or add an event listener on the window object. Provide an event handler function. Access relevant properties on the event or window objects.


4 Answers

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.

like image 125
Daniele Ricci Avatar answered Oct 23 '22 17:10

Daniele Ricci


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.

like image 24
Guerric P Avatar answered Oct 23 '22 17:10

Guerric P


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>
like image 30
Simone Aronica Avatar answered Oct 23 '22 17:10

Simone Aronica


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

like image 40
mohamadHammad Avatar answered Oct 23 '22 16:10

mohamadHammad