Javascript 检测新的鼠标滚轮事件
我正在使用以下事件侦听器检测鼠标滚轮和滚动方向:Javascript 检测新的鼠标滚轮事件,javascript,mousewheel,Javascript,Mousewheel,我正在使用以下事件侦听器检测鼠标滚轮和滚动方向: window.addEventListener('wheel', ({ deltaY }) => { console.log(deltaY); if (deltaY > 0) scrollDown(); else if (deltaY < 0) scrollUp(); }); window.addEventListener('wheel',({deltaY})=>{ 控制台日志(deltaY); 如果(deltaY
window.addEventListener('wheel', ({ deltaY }) => {
console.log(deltaY);
if (deltaY > 0) scrollDown();
else if (deltaY < 0) scrollUp();
});
window.addEventListener('wheel',({deltaY})=>{
控制台日志(deltaY);
如果(deltaY>0)向下滚动();
否则如果(deltaY<0)向上滚动();
});
这里发生了以下情况:
- Macbook上的双指触摸板滚动会触发事件处理程序
由于滚动加速度计而保持日志记录deltaY
或scrollDown()
持续启动,直到加速计停止scrollUp()
向上滚动
和向下滚动
。因此,我需要检测新的鼠标滚动事件,而不是每个鼠标滚动事件。这可能吗
我确实尝试了一个超时来检测是否由于加速计的原因,deltaY
仍在变化,但这还不够,因为如果加速计仍在变化,第二次用户交互不会触发向上滚动
或向下滚动
下面是我试图实现的一个代码笔:
它非常接近所需的功能,但是如果您在第一张幻灯片上用力敲击鼠标滚轮,然后尝试立即滚动到下一张幻灯片,超时解决方案会将其锁定,因此您必须再等待一秒钟左右,直到超时完成,然后才能继续滚动。您是否尝试将其拆分为带有标志的函数,以检查是否发生了交互 例如:
// Create a global variable which will keep track of userInteraction
let shouldScroll = true;
// add the event listener, and call the function when triggered
window.addEventListener('wheel', () => myFunction());
//Create a trigger function, checking if shouldScroll is true or false.
myFunction(){
shouldScroll ? (
if (deltaY > 0) scrollDown();
else if (deltaY < 0) scrollUp();
// Change back to false to prevent further scrolling.
shouldScroll = false;
) : return;
}
/* call this function when user interaction occurs
and you want to allow scrolling function again.. */
userInteraction(){
// set to true to allow scrolling
shouldScroll = true;
}
//创建一个全局变量,用于跟踪用户交互
让shouldcoll=true;
//添加事件侦听器,并在触发时调用该函数
addEventListener('wheel',()=>myFunction());
//创建一个触发器函数,检查shouldScroll是true还是false。
myFunction(){
应该滚动吗(
如果(deltaY>0)向下滚动();
否则如果(deltaY<0)向上滚动();
//更改回false以防止进一步滚动。
shouldcoll=false;
):返回;
}
/*当发生用户交互时调用此函数
您想再次允许滚动功能*/
用户交互(){
//设置为true以允许滚动
shouldcoll=true;
}
我们可以通过延迟执行和删除延迟之间的事件来避免这种情况,参考下面的示例,并添加了1000毫秒作为延迟,可以根据您的要求进行修改
let scrollPage = (deltaY)=>{
console.log(deltaY);
if (deltaY > 0) scrollDown();
else if (deltaY < 0) scrollUp();
};
var delayReg;
window.addEventListener('wheel', ({ deltaY }) => {
clearTimeout(delayReg);
delayReg = setTimeout(scrollPage.bind(deltaY),1000);
});
let scrollPage=(deltaY)=>{
控制台日志(deltaY);
如果(deltaY>0)向下滚动();
否则如果(deltaY<0)向上滚动();
};
var-delayReg;
addEventListener('wheel',({deltaY})=>{
clearTimeout(delayReg);
delayReg=setTimeout(scrollPage.bind(deltaY),1000);
});
这是一个古老的问题,但我在寻找几乎相同问题的答案时发现了它。
我解决这个问题是出于我的目的,所以这里是我的解决方案,以防它对其他人有帮助
问题是如何定义一个连续的动作。如果没有更具体的工作,这只是时间问题。关键是事件之间的时间,所以算法是不断累积事件,直到它们之间有一定的间隔。接下来剩下的就是计算出允许的差距应该有多大,这是解决方案特有的。这是用户停止滚动直到收到反馈后的最大延迟。我的最佳值是四分之一秒,我在下面的示例中将其用作默认值
下面是我的JavaScript,我使用jQuery将事件附加到id为“wheelTestDiv”的div,但它对窗口对象的作用与问题中的相同
值得注意的是,下面的内容查找任何onWheel
事件,但仅跟踪Y轴。如果您需要更多轴,或者只想在deltaY
发生更改时对计时器中的事件进行计数,则需要适当地更改代码
同样值得注意的是,如果您不需要针对不同的DOM对象跟踪事件的灵活性,那么您可以重构类,使其具有静态方法和属性,这样就不需要创建全局对象变量。如果您确实需要跟踪不同的DOM对象(我需要),那么您可能需要该类的多个实例
"use strict";
class MouseWheelAggregater {
// Pass in the callback function and optionally, the maximum allowed pause
constructor(func, maxPause) {
this.maxAllowedPause = (maxPause) ? maxPause : 250; // millis
this.last = Date.now();
this.cummulativeDeltaY = 0;
this.timer;
this.eventFunction = func;
}
set maxPause(pauseTime) {
this.maxAllowedPause = pauseTime;
}
eventIn(e) {
var elapsed = Date.now() - this.last;
this.last = Date.now();
if ((this.cummulativeDeltaY === 0) || (elapsed < this.maxAllowedPause)) {
// Either a new action, or continuing a previous action with little
// time since the last movement
this.cummulativeDeltaY += e.originalEvent.deltaY;
if (this.timer !== undefined) clearTimeout(this.timer);
this.timer = setTimeout(this.fireAggregateEvent.bind(this),
this.maxAllowedPause);
} else {
// just in case some long-running process makes things happen out of
// order
this.fireAggregateEvent();
}
}
fireAggregateEvent() {
// Clean up and pass the delta to the callback
if (this.timer !== undefined) clearTimeout(this.timer);
var newDeltaY = this.cummulativeDeltaY;
this.cummulativeDeltaY = 0;
this.timer = undefined;
// Use a local variable during the call, so that class properties can
// be reset before the call. In case there's an error.
this.eventFunction(newDeltaY);
}
}
// Create a new MouseWheelAggregater object and pass in the callback function,
// to call each time a continuous action is complete.
// In this case, just log the net movement to the console.
var mwa = new MouseWheelAggregater((deltaY) => {
console.log(deltaY);
});
// Each time a mouse wheel event is fired, pass it into the class.
$(function () {
$("#wheelTestDiv").on('wheel', (e) => mwa.eventIn(e));
});
“严格使用”;
类鼠标轮聚合器{
//传入回调函数和(可选)允许的最大暂停时间
构造函数(func、maxPause){
this.maxAllowedPause=(maxPause)?maxPause:250;//毫秒
this.last=Date.now();
this.cumulativedeltay=0;
这个计时器;
this.eventFunction=func;
}
设置最大暂停(暂停时间){
this.maxAllowedPause=pauseTime;
}
事件素(e){
var expead=Date.now()-this.last;
this.last=Date.now();
if((this.cumulativedeltay==0)| |(经过<!DOCTYPE html>
<html>
<head>
<title>Mouse over test</title>
<script src="/mouseWheelEventManager.js"></script>
</head>
<body>
<div id="wheelTestDiv" style="margin: 50px;">Wheel over here</div>
</body>
</html>