禁用预测滚动 - 鼠标滚轮(OnScroll)事件频繁触发(触摸板) - JS

时间:2016-01-16 19:23:28

标签: javascript jquery javascript-events touch mousewheel

我正在执行javascript onScroll。 我的代码适用于任何普通的电脑鼠标,但当我使用我的笔记本触摸板时,我会遇到以下情况:

  • 我的鼠标在手指移动方向盘时发出(大约1到8个)鼠标轮事件。
  • 我的触控板发出更多(约60)鼠标滚轮事件,同时两根手指触碰垫并在我的手指再次抬起后再继续发射。

我从移动触控设备了解这种行为。该功能被称为" Predictive Touch" - 如果在抬起手指之前手指移动有足够的加速度,滚动会继续。

我认为触控板驱动程序正在设置这个"平滑滚动"行为。

为了调试这种情况,我使用了以下代码:

/* Handle Mouse-Wheel Scrolling */
var lastChange = +new Date();
$(window).bind('mousewheel',    function(e){
    console.log("mw");
    if(+new Date() - lastChange > 1000){
        console.log("mw allowed");
        if(e.originalEvent.wheelDelta > 0)  {/*go to previous*/}
        else{   /*go to next*/}
        lastChange = +new Date();
    }
return false;});

这是一个简单的代码,"允许"每秒一次鼠标滚动事件。

如果我进行快速触摸板滚动,鼠标滚轮事件将被触发约300次。一秒钟的条件是让3个事件发生。我的手指在触摸板上的时间不到一秒钟。

通过这项测试,我发现即使我的手指已经离开触控板,鼠标滚轮事件仍会被触发(几乎连续持续3秒)。

是否有Javascript函数或变通方法/技巧/黑客来避免此行为?

类似" onTouchEnd"触摸板的事件,也许?

2 个答案:

答案 0 :(得分:1)

编辑:这似乎不适用于触控板。广泛支持后,可以使用Touch Events,特别是Touch End事件来实施。通过跟踪手指何时离开触控板,可以防止页面在该特定点滚动。

https://jsfiddle.net/gLkkb5z0/3/

(function(){

    var special = jQuery.event.special,
        uid1 = 'D' + (+new Date()),
        uid2 = 'D' + (+new Date() + 1);

    special.scrollstart = {
        setup: function() {

            var timer,
                handler =  function(evt) {

                    var _self = this,
                        _args = arguments;

                    if (timer) {
                        clearTimeout(timer);
                    } else {
                        evt.type = 'scrollstart';
                        jQuery.event.handle.apply(_self, _args);
                    }

                    timer = setTimeout( function(){
                        timer = null;
                    }, special.scrollstop.latency);

                };

            jQuery(this).bind('scroll', handler).data(uid1, handler);

        },
        teardown: function(){
            jQuery(this).unbind( 'scroll', jQuery(this).data(uid1) );
        }
    };

    special.scrollstop = {
        latency: 300,
        setup: function() {

            var timer,
                    handler = function(evt) {

                    var _self = this,
                        _args = arguments;

                    if (timer) {
                        clearTimeout(timer);
                    }

                    timer = setTimeout( function(){

                        timer = null;
                        evt.type = 'scrollstop';
                        jQuery.event.handle.apply(_self, _args);

                    }, special.scrollstop.latency);

                };

            jQuery(this).bind('scroll', handler).data(uid2, handler);

        },
        teardown: function() {
            jQuery(this).unbind( 'scroll', jQuery(this).data(uid2) );
        }
    };

})();

Demo

取自http://james.padolsey.com/javascript/special-scroll-events-for-jquery/

答案 1 :(得分:1)

要实现这一目标,您必须区分鼠标滚动事件和触摸板事件,这些事件(使用JavaScript)尚未实现。它已被问及How to capture touch pad input

Pointer Events目前处于编辑草案状态,但尚未得到任何浏览器的支持。另请参阅touch events docs on MDN