为什么窗口滚动事件无法触发

时间:2020-07-14 21:39:10

标签: javascript webpack scroll event-handling dom-events

我有这个js类:

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

我以前已经使用过,但是对于这个特定项目,该事件未触发。

我这样加载它:

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

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

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

问题在于,即使开发人员的控制台未触发任何错误,该事件也永远不会触发。

即使我在开发者控制台中输入(同样,没有错误),也没有

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

在我键入时,哪些会在stackoverflow中被触发。

enter image description here

这可能是什么原因?应用程序中的某个位置正在阻止事件传播?如果是这样,有什么线索如何找到它?其他猜测? (它是一个继承的项目)

4 个答案:

答案 0 :(得分:3)

可能是某些元素(body本身或嵌套的div)的css overflow属性设置为scroll

要尝试确定是哪个,可以添加以下内容:

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

请确保在页面完全呈现后运行它;那么在您的控制台中,您应该有足够的数据来标识元素在滚动。

答案 1 :(得分:3)

window不能滚动而不发出scroll事件。您可以通过单击开发人员工具中的<!DOCTYPE html>元素来验证某些第三方代码没有删除事件侦听器(也可以运行getEventListeners(window).scroll):

enter image description here

如果您看到事件监听器,那么您实际上在应用程序中正在滚动另一个元素:

整页窗口滚动的示例:

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

示例,您可能会认为您在滚动窗口,但实际上是在滚动整页的基础元素:

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>

在这种情况下,事件不会冒泡,并且您无法在window级别收听它。

答案 2 :(得分:3)

这可能是因为元素滚动不是主体。以这个片段为例。我将滚动绑定到主体,但是由于元素滚动是而不是主体,因此不会触发该元素。您应该检查一下样式和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>

答案 3 :(得分:0)

在上一个项目中我遇到了这个问题,您需要填写html的引号 解决方案是

   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="iliakan@gmail.com"><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>`

它正常工作

the result of scrolling