JavaScript- 防抖
前言
说到防抖,很多人会不明白是什么意思?举个简单的例子,在游戏里,防抖就类似王者荣耀里的回城,被打断了就得重新回城;在代码里,防抖就是触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间。我们如何实现防抖呢?
防抖
防抖主要是围绕触发事件、setTimeout、clearTimeout 这三个功能来进行防抖操作的
假设为了防止用户多次点击操作按钮,因此我们需要进行防抖操作,前面说到触发事件,因此我们用到 addEventListener,按钮被点击后就会触发 addEventListener 里面的函数,我们需要延迟执行 addEventListener 里面的函数,就需要用到 setTimeout 了,仅仅延迟执行还不够,用户继续点击按钮的话需要清除延时,还得加入 clearTimeout
举个简单的案例演示,新建一个按钮,在 js 里获取这个按钮,创建一个函数,这个函数表示事件触发要执行的任务,最后给按钮添加事件监听,点击一下按钮就会有正常的监听效果
接下来要进行防抖设置了,创建一个防抖函数并把事件触发执行的任务设置为这个防抖函数,明显要在防抖函数里执行原来的任务,这就需要为防抖函数设置一个参数,并且执行这个参数
但是这样在定义监听函数的时候就直接执行了函数,这是防抖的第一个难点,为了解决我们需要用高级函数,就是在函数里返回函数,刷新后就没有错误了
接下来就可以设置延时了,在返回函数里加一个 setTimeout,在里面执行 btnClick 这个函数,同时也在防抖函数里新增第二个参数,作为延时的事件,延时效果就出来了
有延时就有清除延时,在定义监听时间的时候就定义一个变量,所有独立的执行函数都能访问到这个变量,而且这个变量只创建了一次,只需要不断给变量赋值进行延时,然后在返回函数里清除延时
连续点击多次控制台也只显示一条信息,看似防抖函数实现了,但是还有一个地方被我们忽略了
在事件触发要执行的任务的函数里打印 this,看看 this 的指向,this 的指向应该是指向 button 的但是控制台显示指向了 window。因为回调的原因,运行时已经在 window 下了,所以我们要在延时之前把 this 保存下来,此时 this 指向按钮,在延时中用 call 来绑定这个 this 给事件触发要执行的任务的函数,最后控制台打印正确
版权声明: 本文为 InfoQ 作者【格斗家不爱在外太空沉思】的原创文章。
原文链接:【http://xie.infoq.cn/article/d0c34d17c70a776ba87d71be0】。文章转载请联系作者。
评论