欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

笔记本触摸板滑动事件导致连滑的解决方式

程序员文章站 2022-06-01 13:28:05
...

Google了一下,发现并没有关于笔记本触摸板的事件。

在MDN的WheelEvent事件中是这样描述的:

WheelEvent DOM事件会在用户滚动鼠标滚轮或操作其它类似鼠标的设备时触发。

也就是说笔记本触摸板的事件被解释为模拟鼠标滚轮的事件。

举个栗子,经常用到的双指上/下滑动会返回什么,可以copy下面代码到控制台试一下

windowAddMouseWheel();
function windowAddMouseWheel() {
    var scrollFunc = function (e) {
        e = e || window.event;
        if (e.wheelDelta > 0) { //当滑轮向上滚动时
            console.log("滑轮向上滚动");
        }
        if (e.wheelDelta < 0) { //当滑轮向下滚动时
            console.log("滑轮向下滚动");
        }
    };
    //给页面绑定滑轮滚动事件
    if (document.addEventListener) {
        document.addEventListener('DOMMouseScroll', scrollFunc, false);
    }
    //滚动滑轮触发scrollFunc方法
    window.onmousewheel = document.onmousewheel = scrollFunc;
}
复制代码

操作都是一次,鼠标滑轮上or下一次,触摸板上or下滑一次,结果如图

可见触摸板虽然模拟了鼠标的滚轮事件,但默认模拟了多次,这也就是为什么用触摸板滑动会有“惯性”的原因。

那么问题来了,我在实际使用中就碰到了这样的问题。

我需要实现fullpage的效果(全屏滚动翻页),监听滚轮事件之后便可判断上or下滚动,进行模拟全屏翻页动画。但是问题就在笔记本的触摸板进行操作的时候,传来了n个滚动事件,此时,只要触摸板划一次,就会执行多次动画,翻了很多页。

以下讨论只针对触摸板滑动。

那么应该如何解决呢?利用节流和防抖?网上已经有很多节流和防抖的原理与实现教程了,这里不在细说。但目前并没有针对这种情况的解决方式。

如果等到防抖结束后(n个滑动事件结束后)且过一段时间(设置的节流时间)才翻页,这么长的时间会严重影响到用户体验。如果节流呢?需要等到节流设置时间到达时第一次翻页,但这个时间为自己设置的,设置的太短的话,依然会触发多次,但太长的话又依然影响到用户体验。

所以针对以上需求,如下代码可以解决

function throttle(func,delay,immediate){
    //func为需要节流的函数,delay为节流的时间,immediate为是否需要先执行
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        if(timer) clearTimeout(timer);
        if(immediate){
            //根据距离上次触发操作的时间是否到达delay来决定是否要现在执行函数
            var doNow = !timer;
            //每一次都重新设置timer,就是要保证每一次执行的至少delay秒后才可以执行
            timer = setTimeout(function(){
                timer = null;
            },delay);
            //立即执行
            if(doNow){
                func.apply(context,args);
            }
        }else{
            timer = setTimeout(function(){
                func.apply(context,args);
            },delay);
        }
    }
}
复制代码

一旦滑动,先执行,这样用户在翻页的时候并不会感到明显延迟。 但这并不是最优解,触发翻页后,需要等待翻页所出发的setTimeout事件完全终止时,下一次的翻页事件才有效。

如果有更好的方式能解决这个问题,欢迎讨论。

转载于:https://juejin.im/post/5c21f24af265da6136227d77