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事件完全终止时,下一次的翻页事件才有效。
如果有更好的方式能解决这个问题,欢迎讨论。