OSX惯性滚动导致mousewheel.js以最轻微的滚动动作注册多个鼠标滚轮事件

我有一个非常标准的Flexslider实例,我正在努力。 Flexslider与jquery.mousewheel.js插件完美结合,允许幻灯片在鼠标滚轮事件上移动。

但是,Mac OSX和其他人使用“intertia”滚动效果,几乎不可能只向左或向右滚动一张幻灯片。 一般效果是,即使在这些情况下最轻微的滚动运动也会触发多个鼠标滚轮事件,并向左或向右滚动滑块多个图像。 显然,这不可能发生!

我认为解决方案是使用underscore.js – 特别是’去抖’function。 但是,我在JS / jQuery方面相对缺乏经验,无法弄清楚如何实现它。

从下划线的文档:

去抖: _.debounce(function, wait, [immediate])

创建并返回传递函数的新debounced版本,该函数将推迟执行,直到自上次调用之后经过等待毫秒。 用于实现仅在输入停止到达后才会发生的行为。 例如:呈现Markdown注释的预览,在窗口停止resize后重新计算布局,等等。

对于立即参数传递true会导致去抖动以在前导而不是等待间隔的后沿触发函数。 在防止第二次触发“提交”按钮时意外双击的情况下非常有用。

 var lazyLayout = _.debounce(calculateLayout, 300); $(window).resize(lazyLayout); 

这是我用来初始化flexslider的代码:

 // MOUSEWHEEL FIX: function debounceEffect() { // apply debounce to mousewheel here } // Initialize FlexSlider $(window).load(function() { $('div.flexslider').flexslider({ animation:'slide', controlNav:true, mousewheel:true, pauseOnHover:true, direction:'horizontal', animationSpeed:500, slideshowSpeed:5000, after:debounceEffect }); }); 

不幸的是,我无法弄清楚如何将去抖function应用于鼠标滚轮事件。 我想我只是不太了解运动部件。

以下是flexslider插件的相关代码 :

  // MOUSEWHEEL: if (vars.mousewheel) { slider.bind('mousewheel', function(event, delta, deltaX, deltaY) { event.preventDefault(); var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev'); slider.flexAnimate(target, vars.pauseOnAction); }); } 

我可以编辑它以包含一些mousewheel插件代码,如果这很重要,或者你可以在github上查看它。

我将不胜感激任何帮助!

我认为主要问题是你不能将debouncing作为后效应用,或者至少我不知道如何。 让我们来谈谈这些部分是如何工作的:

当你调用$('div.flexslider').flexslider({ .. } ,jQuery找到像div.flexslider这样的所有元素(像往常一样),然后添加一个flexslider.flexslider添加所有的机制,使它成为一个滑块,包括设置绑定事件。这是你需要去抖动的实际绑定事件本身。

通过找到相关的flexslider绑定代码,您似乎非常接近。 我认为你理想的是这个:

 if (vars.mousewheel) { slider.bind('mouse wheel', _.debounce(function(…) { // usual flex slider code. }), 300); } 

如果不直接编辑flexslider代码,我不确定你是如何实际注入此debounce的。

如果你想全局影响鼠标滚轮事件(我猜你可能会),你可能会去掉鼠标滚轮插件本身。 我认为你必须将处理程序包装在debounce中,然后将debounced-handler传递给addEventListener和removeEventListener 。

看起来这个问题仍然存在。

我使用这个debounce 插件和更改flexslider.js得到了一些好的结果,所以它是以下:

 slider.bind('mousewheel', $.debounce( 100, true, function(event, delta, deltaX, deltaY){ event.preventDefault(); var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev'); slider.flexAnimate(target, slider.vars.pauseOnAction); })); 
Interesting Posts