简体   繁体   English

为什么 window 滚动事件不会被触发

[英]Why could window scroll event not being fired

I have this js class:我有这个 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.当我打字时,它在stackoverflow中被触发。

在此处输入图像描述

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 ) (它是一个继承的项目)

It could be that some element (the body itself or some nested div ) has the css overflow property set to scroll .可能是某些元素( body本身或某些嵌套的div )将 css overflow属性设置为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.然后在您的控制台中,您应该有足够的数据来识别哪个元素正在滚动。

The window can't be scrolling without emitting scroll events. window不能在不发出scroll事件的情况下滚动。 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 ):您可以通过单击开发人员工具中的<!DOCTYPE html>元素来验证某些第三方代码是否没有删除事件侦听器(您也可以运行getEventListeners(window).scroll ):

在此处输入图像描述

If you see the event listener, then in your app you are actually scrolling another element:如果您看到事件侦听器,那么在您的应用程序中您实际上正在滚动另一个元素:

Example of full page window scroll:整页 window 滚动示例:

 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 但实际上正在滚动整页底层元素的示例:

 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.在这种情况下,事件不会冒泡,您无法在window级别收听它。

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.你应该检查你的风格和你的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>

i faced this problem during last project you need to fill the quotation of html the solution is我在上一个项目中遇到了这个问题,您需要填写 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>`

it is work correctly它工作正常

the result of scrolling滚动的结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM