【发布时间】:2021-09-04 21:27:49
【问题描述】:
我正在为年幼的孩子创建一个网络应用程序,他们可以在其中水平滚动非常宽的图片。年幼的孩子可能会疯狂地滑动触摸屏。我想允许惯性滚动(因为它很有趣),但要限制它,以便儿童用户不会快速向后和向前滚动到最后,错过中间的所有好东西。
在惯性滚动期间,会生成mousewheel 事件。我曾希望在此事件中使用event.preventDefault(),以便在特定点停止惯性滚动。但是,似乎如果您不在特定操作中的第一个 mousewheel 事件上运行 preventDefault(),则不会阻止以下事件。
下面的代码 sn-p 提供了一个演示。它包含一个可以滚动的元素,直到其 scrollLeft 的值达到 5000。JavaScript 包含一个 mousewheel 事件侦听器,当 scrollLeft 的值大于 2500 时,它会显式调用 event.preventDefault()。
我曾希望这会中途停止惯性滚动。但是没有。
运行 sn-p 然后使用鼠标垫(或触摸屏)向左滑动可滚动元素。你会看到:
- 如果您提供足够的惯性,元素将滚动一直向左。对
event.preventDefault()的条件调用无效。 -
mousewheel事件持续发出最多 5 秒(取决于您用于滑动的能量)。即使元素完全向左滚动,它们也会继续发射。
但是,如果您向左滚动超过 2500,然后尝试向右滑动,则不会发生任何事情。 first mousewheel 事件的默认操作被阻止,因此惯性滚动永远不会开始。
我的问题是:在滚动到达某个点后,有没有办法完全阻止 mousewheel 事件的发出?额外问题:有没有办法确定特定滑动手势的惯性大小?
我有一个解决方法来限制scrollLeft 的值,但这意味着在发出最后一个mousewheel 事件之前,孩子将无法再次滑动。
const output = document.getElementById("output");
const container = document.getElementById("container");
container.addEventListener("mousewheel", mousewheel, false);
let startTime = 0
let timeOut = 0
function mousewheel(event) {
const time = getTime()
const scrollLeft = Math.round(container.scrollLeft * 10) / 10;
output.innerText = time + "s\n" + scrollLeft;
clearTimeout(timeOut)
timeOut = setTimeout(() => startTime = 0, 100)
if (scrollLeft > 2500) {
event.preventDefault();
return false;
}
}
function getTime() {
const time = + new Date()
if (!startTime) {
startTime = time;
}
return (time - startTime) % 10000 / 1000
}
body {
margin: 0;
height: 100px;
}
div#container {
width: 500px;
height: 100%;
background-color: green;
overflow: auto;
}
div#content {
width: 5500px; /* Allows scrollLeft up to 5000 */
height: 100%;
background-color: red;
clip-path: polygon(0 0, 100% 0, 100% 100%)
}
<div id="container">
<div id="content"></div>
</div>
<pre id="output">0</p>
【问题讨论】:
标签: javascript html mousewheel eventemitter