基于 Opera 12 实现的系统级 scroll 事件防抖 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
autoxbc
V2EX    浏览器

基于 Opera 12 实现的系统级 scroll 事件防抖

  •  
  •   autoxbc 2017-08-05 07:58:06 +08:00 3053 次点击
    这是一个创建于 3060 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前情提要: 在 为何 iOS 的 scroll 阻塞 dom 机制没被大规模借鉴? 中提到,iOS 的 UIWebView 有个特性,页面滚动时会阻塞 js 的 scroll 事件触发和 css 的页面重绘,大大提高了滚动性能。本质上说,这是在前端开发者之外,在浏览器上实现的 scroll 防抖优化,哪怕程序员并不需要(破坏一致性)

    作为用户我是需要的,因为有些人写的代码实在不靠谱。我要在桌面浏览器上实现同样的功能,即对那些包含糟糕滚动性能的页面,统一加上 scroll 防抖处理:对一连串 scroll 动作,只在最后触发一个 scroll 事件,哪怕开发者没做任何防抖和节流。

    在 Opera 12 浏览器中,存在一个全局 Opera 对象,提供一些堪称魔法的函数,让用户对网页事件流做细致的调整,举个例子:
    有些网页会监听用户的 copy 动作,显示一个难看的提示框,我们这么处理

    opera.addEventListener('BeforeEventListener.copy',function(e){ e.preventDefault(); }); 

    哪怕不知道回调函数,对 copy 事件的监听也被去除了,这个方法是本文的核心。

    为了观察 scroll 是否完全停止,用一个全局变量保存 scroll 事件的时间戳。

    window.lastScroll = new Date(); 

    为了即使自己的其他代码禁用 scroll 事件,也可以正确的记录时间戳,同样使用 Opera 对象

    opera.addEventListener('AfterEvent.scroll', function (e){ window.lastScroll = e.timeStamp ; }); 

    即使 scroll 事件不触发,Opera 也可以捕获 AfterEvent.scroll 事件,时间戳是一样的。

    下面对 scroll 事件做防抖,不要介意我的渣代码

    opera.addEventListener('BeforeEventListener.scroll',function(e){ // 阻止事件触发,禁用原有的回调 e.preventDefault(); var callee = arguments.callee ; // timer 为事件墙,只让第一个 scroll 事件通过,其他废弃 if( callee.timer ) return; // 首次滚动立即延迟,观察有无后续滚动 // 同时记录时间戳 callee.timer = setTimeout( function(){ // 高于阈值,滚动完全结束,进入回调组装流程 if( new Date() - window.lastScroll > 800 ) { // 清理事件墙 callee.timer = null ; // 提取原来的回调函数 e.listener // 提取原来的 scroll 事件 e.event // 组合并触发回调 e.listener(e.event); } else { // 低于阈值,滚动未结束,继续延迟回调 // 同时更新时间戳 callee.timer = setTimeout( arguments.callee , 400 ); } } , 400 ); }); 

    这段代码的逻辑是,从开发者对 scroll 的监听过程捕获 BeforeEventListener.scroll 事件,提取其中的 scroll 事件( e.event ),回调函数( e.listener ),按照一定的逻辑重新组装到一起,或者立即触发,或者延迟执行。

    在延迟的过程中,对一串 scroll 事件,只在滚动停止后触发一次。

    至此,借助浏览器提供的专有对象,实现了 scroll 事件的系统级防抖处理,滚动体验被大大提升。在我有限的认知里,没有其他浏览器有这么强的内置功能,可以实现类似的效果。如果 Chrome 或者 Firefox 能够做到,请留言告诉我。

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2616 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 48ms UTC 09:09 PVG 17:09 LAX 01:09 JFK 04:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86