为什么 window 滚动事件不会被触发
Why could window scroll event not being fired
我有这个 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
我之前已经使用过,但是对于这个特定项目,事件没有被触发。
我是这样加载的:
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
})
在我输入时在 Whosebug 中触发。
可能是什么原因?应用程序中的某处正在停止事件传播?如果是这样,任何线索如何找到它?其他猜测? (它是一个继承的项目)
可能是某些元素(body
本身或某些嵌套的 div
)将 css overflow
属性 设置为 scroll
.
要尝试确定哪个是您可以添加如下内容:
document.querySelectorAll("*").forEach(element => element.addEventListener("scroll", ({target}) => console.log(target, target.id, target.parent, target.parent.id)));
请确保在页面完全呈现时 运行 它;那么在您的控制台中,您应该有足够的数据来识别哪个元素正在滚动。
如果不发出 scroll
事件,window
将无法滚动。您可以通过单击开发人员工具中的 <!DOCTYPE html>
元素来验证某些第三方代码是否没有删除事件监听器(您也可以 运行 getEventListeners(window).scroll
):
如果您看到事件侦听器,那么在您的应用中您实际上正在滚动另一个元素:
整页示例 window 滚动:
window.addEventListener('scroll', function() {
console.log('Scroll event');
});
#big-content {
height: 1000px;
}
<div id="big-content">
</div>
您可能认为自己正在滚动 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>
在那种情况下,事件不会冒泡,您无法在 window
级别收听它。
这可能是因为滚动的元素不是正文。以这个片段为例。我将滚动绑定到正文,但由于元素滚动是而不是正文,因此不会触发该元素。你应该检查一下你的风格和你的 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>
我在上一个项目中遇到过这个问题你需要填写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
我有这个 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
我之前已经使用过,但是对于这个特定项目,事件没有被触发。
我是这样加载的:
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
})
在我输入时在 Whosebug 中触发。
可能是什么原因?应用程序中的某处正在停止事件传播?如果是这样,任何线索如何找到它?其他猜测? (它是一个继承的项目)
可能是某些元素(body
本身或某些嵌套的 div
)将 css overflow
属性 设置为 scroll
.
要尝试确定哪个是您可以添加如下内容:
document.querySelectorAll("*").forEach(element => element.addEventListener("scroll", ({target}) => console.log(target, target.id, target.parent, target.parent.id)));
请确保在页面完全呈现时 运行 它;那么在您的控制台中,您应该有足够的数据来识别哪个元素正在滚动。
如果不发出 scroll
事件,window
将无法滚动。您可以通过单击开发人员工具中的 <!DOCTYPE html>
元素来验证某些第三方代码是否没有删除事件监听器(您也可以 运行 getEventListeners(window).scroll
):
如果您看到事件侦听器,那么在您的应用中您实际上正在滚动另一个元素:
整页示例 window 滚动:
window.addEventListener('scroll', function() {
console.log('Scroll event');
});
#big-content {
height: 1000px;
}
<div id="big-content">
</div>
您可能认为自己正在滚动 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>
在那种情况下,事件不会冒泡,您无法在 window
级别收听它。
这可能是因为滚动的元素不是正文。以这个片段为例。我将滚动绑定到正文,但由于元素滚动是而不是正文,因此不会触发该元素。你应该检查一下你的风格和你的 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>
我在上一个项目中遇到过这个问题你需要填写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