禁用预测滚动-鼠标滚轮(OnScroll)事件触发次数过多(触摸板)

问题描述 投票:8回答:2

我正在执行Javascript onScroll。我的代码对任何普通的计算机鼠标都适用,但是当我使用笔记本的触摸板时,会遇到以下情况:

  • 当手指移动滚轮时,我的鼠标触发(大约1到8)mousewheel事件。
  • 我的触摸板在两只手指触摸板时触发了更多(〜60)mousewheel事件并且当我的手指再次悬空时继续触发。

我从移动触摸设备知道这种行为。该功能称为“ 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;});

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

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

通过此测试,我发现mousewheel事件仍被触发(几乎连续3秒),即使我的手指已经离开触摸板。

是否有Javascript函数或替代方法/技巧/ hack来避免此行为?

有点像触摸板的onTouchEnd事件,也许吗?

javascript jquery touch jquery-events mousewheel
2个回答
1
投票

要实现这一点,您必须区分鼠标滚动事件和触摸板事件,但使用JavaScript尚不可能。已经有人问How to capture touch pad input

Pointer Events当前处于编辑器的草稿状态,尚不受任何浏览器支持。另请参阅touch events docs on MDN


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/

© www.soinside.com 2019 - 2024. All rights reserved.