我正在使用 Jquery鼠标滚轮插件,我希望能够检测用户何时完成使用滚轮。与 stop: 可拖动内容中的事件类似的功能。有人可以指出我正确的方向吗?
5 回答
这里真的没有“停止”事件 - 当你滚动时你会得到一个事件,所以每次发生鼠标滚轮事件时都会触发事件......当什么都没有时你不会得到任何事件并且你的处理程序不会被触发。
但是,您可以检测到用户在 250 毫秒内没有使用它的时间,如下所示:
$("#myElem").mousewheel(function() {
clearTimeout($.data(this, 'timer'));
$.data(this, 'timer', setTimeout(function() {
alert("Haven't scrolled in 250ms!");
//do something
}, 250));
});
你可以在这里试一试,我们所做的就是在 using 中存储每次使用的超时时间$.data()
,如果你在该时间用完之前再次使用它,它会被清除......如果不是那么你想要运行的任何代码都会触发,用户在您测试的任何时间段内都“完成”了使用鼠标滚轮。
要完成 Nick Craver 的回答:
var wheeldelta = {
x: 0,
y: 0
};
var wheeling;
$('#foo').on('mousewheel', function (e) {
if (!wheeling) {
console.log('start wheeling!');
}
clearTimeout(wheeling);
wheeling = setTimeout(function() {
console.log('stop wheeling!');
wheeling = undefined;
// reset wheeldelta
wheeldelta.x = 0;
wheeldelta.y = 0;
}, 250);
wheeldelta.x += e.deltaFactor * e.deltaX;
wheeldelta.y += e.deltaFactor * e.deltaY;
console.log(wheeldelta);
});
滚动输出:
start wheeling!
Object {x: -1, y: 0}
Object {x: -36, y: 12}
Object {x: -45, y: 12}
Object {x: -63, y: 12}
Object {x: -72, y: 12}
Object {x: -80, y: 12}
Object {x: -89, y: 12}
Object {x: -97, y: 12}
Object {x: -104, y: 12}
Object {x: -111, y: 12}
Object {x: -117, y: 12}
Object {x: -122, y: 12}
Object {x: -127, y: 12}
Object {x: -131, y: 12}
Object {x: -135, y: 12}
Object {x: -139, y: 12}
Object {x: -145, y: 12}
Object {x: -148, y: 12}
Object {x: -152, y: 12}
Object {x: -154, y: 12}
Object {x: -156, y: 12}
Object {x: -157, y: 12}
Object {x: -158, y: 12}
Object {x: -159, y: 12}
Object {x: -161, y: 12}
Object {x: -162, y: 12}
Object {x: -164, y: 12}
Object {x: -166, y: 12}
Object {x: -167, y: 12}
Object {x: -169, y: 12}
stop wheeling!
以下是如何实现自己的车轮停止事件。
//initialise the new variables
var wheelMap = new Map;
var deltaXEnded = false;
var deltaYEnded = false;
var previousSwipe = Object;
previousSwipe.timeStamp = 0;
previousSwipe.deltaX = 0;
previousSwipe.deltaY = 0;
var wheelstart = false;
为wheelstop事件创建一个新的 eventListener
我们将从normalWheelEventCallbackFunction()调用
var wheelstop = new Event("wheelstop");
接下来,我们将在此事件被调度的情况下定义回调,然后将事件添加到窗口对象。
function wheelstopcallback(event){
wheelstart = false;
console.log("wheel event has ended");
}
window.addEventListener("wheelstop", wheelstopcallback.bind(this));
现在我们定义正常的车轮事件监听器以及定义这个监听器将使用的回调......
window.addEventListener("wheel", normalWheelEventCallbackFunction.bind(this));
Wheel 事件回调函数
function normalWheelEventCallbackFunction(event){
if(previousSwipe.timeStamp !== 0){
if(event.timeStamp - previousSwipe.timeStamp < 1000)
wheelMap.set(event.timeStamp, event);
else
wheelMap.clear();
}
else{previousSwipe.timeStamp = event.timeStamp;}
if(event.deltaX > 2 && event.deltaX > previousSwipe.deltaX){
//forward
wheelstart = true
}
else if(event.deltaX < -2&& event.deltaX < previousSwipe.deltaX){
//backward
wheelstart = true;
}
else if(event.deltaY > 2 && event.deltaY > previousSwipe.deltaY){
wheelstart = true;
}
else if(event.deltaY < 2 && event.deltaY < previousSwipe.deltaY){
wheelstart = true;
}
if(
((event.deltaX === 1 || event.deltaX === 0 || event.deltaX === -1) && ((event.deltaX > 0 && event.deltaX < previousSwipe.deltaX) || (event.deltaX < 0 && event.deltaX > previousSwipe.deltaX)) && wheelstart)
|| (wheelstart && (event.deltaX === 0 && previousSwipe.deltaX === 0))
)
{
deltaXEnded = true;
console.log("deltaXEnded");
}
if(
(((event.deltaY === 1 || event.deltaY === 0 || event.deltaY === -1) && ((event.deltaY > 0 && event.deltaY < previousSwipe.deltaY) || (event.deltaY < 0 && event.deltaY > previousSwipe.deltaY))) && wheelstart)
|| (wheelstart && (event.deltaY === 0 && previousSwipe.deltaY === 0))) {
deltaYEnded = true;
console.log("deltaYEnded");
}
if(deltaXEnded && deltaYEnded){
deltaXEnded = false;
deltaYEnded = false;
window.dispatchEvent(wheelstop);
}
previousSwipe.deltaX = event.deltaX;
previousSwipe.deltaY = event.deltaY;
}
这可能有一些错误,但在大多数情况下逻辑是相当合理的,我会推荐一个后备但是如果你需要捕获每一个调度的车轮事件,因为它可能有一些在'wheelstop'事件被调度之后。
哦,最后确定并实现一个处理程序,如果它被点击事件中断,从而结束轮子事件......
function wheelstopdispatch(){
if(wheelstart)
window.dispatchEvent(wheelstop);
}
window.addEventListener("click", wheelstopdispatch);
以下是在本机 JavaScript 中执行此操作的方法:
var _scrollTimeout = null;
function onMouseWheel() {
var d = ((typeof e.wheelDelta != "undefined") ? (-e.wheelDelta) : e.detail);
d = 100 * ((d>0)?1:-1);
console.log("Scroll delta", d);
clearTimeout(_scrollTimeout);
_scrollTimeout = setTimeout(function() {
console.log("Haven't scrolled in 250ms");
}, 250);
}
window.addEventListener( 'mousewheel', onMouseWheel, false );
window.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
Nick Craver 的回答很好。但这会导致执行// do something
. 更好的选择是立即执行您的代码并delay
在捕获更多事件之前等待毫秒。
为此,请使用全局变量 say processing
,用它初始化它false
并在代码执行之前和之后切换它的值。
window.processing = false;
$("#myElem").mousewheel(function() {
if (processing === false) {
processing = true;
// do something
setTimeout(function() {
processing = false;
}, 250)); // waiting 250ms to change back to false.
}
});