Jquery,unbinding mousewheel event,then rebinding it after actions are completed?
我正在从delta中挖掘事件树,只定位X鼠标滚轮值.一切都运作良好.我想克服的问题:我想简单地向前/向后滚动一个面板,然后停止滚动.目前,我在移动后立即解除鼠标滚轮事件的绑定,并且有效地停止滚动…但是解除鼠标滚轮事件的绑定也会使页面突然显示.我需要的是能够嗅探方向的第一个deltaX值,然后移动并停止收听.我是否需要查看自动滚动以获取答案?绑定/解除绑定感觉很难,但是我不能,为了我的生活,想出如何在一次移动后踢出,同时仍然能够在移动完成后滚动.这是我的鼠标滚轮功能:
function mouseHandler(event,delta) { $('.homeScrollable').bind('mousewheel',mouseHandler); var deltaX = event.originalEvent.wheelDeltaX; //console.log(event.originalEvent.wheelDeltaX); if(deltaX <= 0) { //move forward 1 screen and stop scrollapi.move(1); $('.homeScrollable').unbind('mousewheel',mouseHandler); } else if(deltaX > 0) { //move backward 1 screen and stop scrollapi.move(-1); $('.homeScrollable').unbind('mousewheel',mouseHandler); } event.preventDefault(); // Rebind mousewheel event: $('.homeScrollable').bind('mousewheel',mouseHandler); };
我也看过设置一个计时器,一个la:
jquery mousewheel plugin: how to fire only one function every scroll
这似乎令人难以置信,但没有去.这是这个家伙的插件页面:
http://brandonaaron.net/code/mousewheel/docs
感谢检查出来.
解决方法
如果快速滚动浏览任何特定元素,则会按顺序多次触发滚动事件.使用以下代码,我们可以准确了解发生的频率:
$('#exampleDiv').bind('mousewheel',function () { console.log(new Date().getTime()); });
当您滚动该div时,您将获得如下所示的控制台输出:
// Using mouse wheelbar 251327626600149 251327626600215 251327626600265 251327626600282 251327626600332 251327626600365 // Using touchpad 251327626626207 251327626626225 251327626626261 251327626626276 251327626626312 251327626626345
看看这个输出,看起来mousescroll事件通常在20毫秒到60毫秒之间的某个地方被触发.为了安全起见,我们将上限设为100 ms.这是非常有用的信息,因为我们可以使用它来区分属于同一动作的滚动事件和可能由用户明确且故意启动的滚动事件.
你可以从这里做的是创建一个全局可访问的’timestamp’变量,每次触发mousescroll事件时更新它,无论是否成功.像这样的东西:
var timeStamp = new Date().getTime(); $('#exampleDiv').bind('mousewheel',function (event) { var timeNow = new Date().getTime(); // Need to prevent the default scrolling behavior event.preventDefault(); // If the last mousescroll happened less that 100 ms ago,update // timeStamp and do nothing if (timeNow - timeStamp < 100) { timeStamp = timeNow; return; } else { timeStamp = timeNow; scrollToSomeOtherDiv(); } });
这有效地忽略了在它们之前的初始事件之后触发的所有mousescroll事件,但在用户暂停100 ms后再次开始工作.
这将解决您的问题,除非您的scrollToSomeOtherDiv()函数涉及某种耗时的动画.您当然可以创建一个全局布尔值isAnimating,并在每次触发mousescroll事件时检查它是否为真(确保在动画结束后将其在回调中变为false).
这可行,除了它可以为用户提供刺耳的体验.即使在看到动画开始后,想要快速滚动两个面板的人也可能不会在滚动之间暂停.上面的代码将看到所有mousescroll事件作为相同滚动动作的一部分,并继续忽略它们!
在这种情况下,您可以简单地使用动画时间作为阈值.您可以在动画开始后设置timeStamp,然后在该段时间内忽略所有mousescroll事件.我在这里写了一个例子:http://jsfiddle.net/Sg8JQ/
相关代码在这里:
var lastAnimation = 0; var animationTime = 1000; // in ms var quietPeriod = 500; // in ms,time after animation to ignore mousescroll function scrollThis(event,delta,deltaX,deltaY) { var timeNow = new Date().getTime(); // change this to deltaX/deltaY depending on which // scrolling dir you want to capture deltaOfInterest = deltaY; if (deltaOfInterest == 0) { // Uncomment if you want to use deltaX // event.preventDefault(); return; } // Cancel scroll if currently animating or within quiet period if(timeNow - lastAnimation < quietPeriod + animationTime) { event.preventDefault(); return; } if (deltaOfInterest < 0) { if ($('.active').next('div').length) { lastAnimation = timeNow; $('.active').removeClass('active').next('div').addClass('active'); $('html,body').animate( { scrollTop: $('.active').offset().top },animationTime); } } else { if ($('.active').prev('div').length) { lastAnimation = timeNow; $('.active').removeClass('active').prev('div').addClass('active'); $('html,animationTime); } } } // Note: mousewheel() is defined in the mousewheel plugin by Brandon Aaron // You could do without it,but you'd need to adjust for firefox and webkit // separately. // // You couldn't use $(document).scroll() because it doesn't allow you to // preventDefault(),which I use here. $(document).mousewheel(scrollThis);
我还包括quietPeriod,这是超出动画时间的时间,在此期间你想继续忽略mousescroll事件.如果您希望动画完成后滚动“响应”,则可以将其设置为0.