摘要:这个来的莫名其妙,问了一圈人也没什么思路,后来自己上网搜,在一个页面上找到一段关于的触控板的手势滑动会疯狂触发滚轮事件的记录,但是轮到具体的解决方案就语焉不详了。
头几天官网刚上线,就接到投诉说有问题。过去一看,我靠什么鬼?!Mac下用触控板一滑到底,——首页上用iscroll写的翻页效果直接全军覆没。
这个bug来的莫名其妙,问了一圈人也没什么思路,后来自己上网搜,在一个页面上找到一段关于Mac的触控板的手势滑动会疯狂触发滚轮事件的记录,但是轮到具体的解决方案就语焉不详了。没辙,靠天没用,还是靠自己吧~
这里先简单介绍下。出问题的首页用的是iscroll插件,用snap属性做的整屏翻页的效果,翻页用鼠标滚轮驱动,这块用的是MDN上的一个滚轮事件的兼容代码,回调使用iscroll的接口完成向上/向下翻页的效果。
回到这个问题上。一开始我想用事件防抖解决,于是用setTimeout()自己写了个:触发事件后先进入延时,延时后执行函数;如果在延时内仍有事件触发,则取消原有的延时重新计时。
// 打底用的zepto.js,addWheelListener是滚轮事件的兼容插件,下同~ var wheelTimer = false; var wheelSlide = function (e) { e.preventDefault(); clearTimeout(timer); if (e.deltaY > 0) { wheelTimer = setTimeout(function(){ iScroll.next(); }, 100); } else if (e.deltaY < 0 && iScroll.currentPage.pageY != 0) { wheelTimer = setTimeout(function(){ iScroll.prev(); }, 100); } } addWheelListener($("body")[0], wheelSlide);
我本意是用延时抵消掉重复触发的滚轮事件,最后合成一个事件触发,没想到测试之后,Mac上的问题并没有解决。
于是我想,用事件防抖的思路处理应该还是不对,即便是延迟时间较短,如果事件持续触发的话肯定翻页还是会被无限的延迟阻塞掉,至此我想换用事件节流再试试。在找资料的时候,意外发现了Underscore.js这个工具库,里边不仅有现成的节流和防抖(中文文档里用的是“防反跳”)函数可以用,而且还支持链式调用,并且压缩版本也才十几k,正合我意。
说干就干,马上用Underscore撸了个事件节流版的:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { iScroll.next(); } else if (e.deltaY < 0 && iScroll.currentPage.pageY != 0) { iScroll.prev(); } }).throttle(400);//这里毫秒数用了400,大概相当于一个短动画的执行时间 addWheelListener($("body")[0], wheelSlide);
链式写法看上去还挺不错的!进本机浏览器(PC)……嗯?为啥最后会跳一下?赶紧翻文档,又加了个参数上去:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { iScroll.next(); } else if (e.deltaY < 0 && iScroll.currentPage.pageY != 0) { iScroll.prev(); } }).throttle(400, {trailing: false}); addWheelListener($("body")[0], wheelSlide);
这回PC上倒是正常了,Mac也从一滑到底变成了有“段落感”的跳动,但结果还是不对……
一狠心把毫秒数改成了5000,结果呢:还、是、不、对、、、。。。
(//陷入循环懵逼状态ing……)
痛定思痛,一定是文档看的不够多!于是又啃了一遍Underscore.js的文档(虽然是翻译的,囧……),发现防抖居然有个[immediate]参数,是可以优先执行的!大喜过望~接着撸:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { wScroll.next(); } else if (e.deltaY < 0 && wScroll.currentPage.pageY != 0) { wScroll.prev(); } }).debounce(600, true);// 本来想改回400的,有点心虚所以又加了200…… addWheelListener($("body")[0], wheelSlide);
居然PC和Mac都能一页页的翻页了有!没!有!不过翻页的动作还有点迟滞,于是果断把毫秒数改小:400、200、100,……Bingo!
最终代码:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { wScroll.next(); } else if (e.deltaY < 0 && wScroll.currentPage.pageY != 0) { wScroll.prev(); } }).debounce(50, true); addWheelListener($("body")[0], wheelSlide);
总结:
Mac触控板bug踩坑 +1;
理解了事件节流和事件防抖的概念;
Underscore.js真好用;
感谢git把每次的修改都记了下来。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/81573.html
摘要:返回的位置矩阵返回的方向矩阵返回轴每秒的角加速度返回轴每秒的角速度返回轴每秒的线性加速度返回轴的线性速度与只有的如和的只包含方向矩阵,因此为而为而的如和由于和兼具,因此和都为。 showImg(https://segmentfault.com/img/remote/1460000011814572?w=680&h=383);上期 WebVR开发教程——交互事件(一)头显与手柄 从头显和...
摘要:译通过实例讲解和防抖与节流源码中推荐的文章,为了学习英语,翻译了一下原文链接作者本文来自一位伦敦前端工程师的技术投稿。首次或立即你可能发现防抖事件在等待触发事件执行,直到事件都结束后它才执行。 [译]通过实例讲解Debouncing和Throtting(防抖与节流) lodash源码中推荐的文章,为了学习(英语),翻译了一下~ 原文链接 作者:DAVID CORBACHO 本文来自一位...
摘要:举例举例通过拖拽浏览器窗口,可以触发很多次事件。不支持,所以不能在服务端用于文件系统事件。总结将一系列迅速触发的事件例如敲击键盘合并成一个单独的事件。确保一个持续的操作流以每毫秒执行一次的速度执行。 Debounce 和 Throttle 是两个很相似但是又不同的技术,都可以控制一个函数在一段时间内执行的次数。 当我们在操作 DOM 事件的时候,为函数添加 debounce 或者 th...
摘要:把事件统一起来处理用户的输入要用到事件。就这样,提取了鼠标触摸屏触控笔的共通之处,以方便开发跨设备的应用。虽然是一个抽象,但它包含了鼠标触摸屏触控笔的全部内容。手指与触摸屏的屏幕接触着,认定为。 跨设备的问题 平时我们在电脑上访问的网页,大部分情况下是用鼠标来控制的。比如说链接跳转,就是鼠标指针移动到链接文字或图片的位置,然后点击一下。又比如说滚动屏幕,滑动一下鼠标滚轮就可以。 如果是...
摘要:把事件统一起来处理用户的输入要用到事件。就这样,提取了鼠标触摸屏触控笔的共通之处,以方便开发跨设备的应用。虽然是一个抽象,但它包含了鼠标触摸屏触控笔的全部内容。手指与触摸屏的屏幕接触着,认定为。 跨设备的问题 平时我们在电脑上访问的网页,大部分情况下是用鼠标来控制的。比如说链接跳转,就是鼠标指针移动到链接文字或图片的位置,然后点击一下。又比如说滚动屏幕,滑动一下鼠标滚轮就可以。 如果是...
阅读 3167·2021-11-23 09:51
阅读 1504·2021-11-22 09:34
阅读 2808·2021-10-27 14:15
阅读 2229·2021-10-12 10:17
阅读 1866·2021-10-12 10:12
阅读 894·2021-09-27 14:00
阅读 1950·2021-09-22 15:19
阅读 978·2019-08-30 10:51