防抖
防抖的原理就是:尽管你触发了许多许多次事件,但是每一次事件触发的时候都会清除上次的事件,并以这次触发事件的时间为开端n秒后才进行事件的真正执行。
1 |
|
以上是测试的html文件
1 | var count = 1; |
以上是JavaScript代码
此测试效果图:
可以看到鼠标滑过div,getUserAction事件被触发了很多次,因为当前事件非常简单所以浏览器能够迅速处理掉,但是如果脚本代码有异步代码,请求数据等,浏览器不能马上处理完,就会造成卡顿。
第一版
1 | function debounce(func, wait) { |
下面是使用效果:
从图中可以看出,事件的触发被限制了。
this
在getUserAction函数里面console.log(this)
,如果没有使用debounce函数,this指向的是Dom节点div,但是一旦使用了debounce函数,this变成指向了window对象。
这时我们需要修正this的指向
第二版
1 | function debounce(func, wait) { |
event对象
Javascript 在事件处理函数中会提供事件对象event,我们修改getUserAction函数:
1 |
|
可以看到,在没有使用debounce函数,打印出来的时MouseEvent对象,
但是在debounce函数中只会打印出undefined。
所以我们来修改下代码:
1 | function debounce(func, wait) { |
以上代码修复了两个小问题:
- this指向
- event对象
立即执行
之前的代码都是让事件在最后一次触发的n秒后才执行,现在有一个新的需求就是,要触发事件就立马执行一次
1 | function debounce(func, wait, immediate){ |
这里是效果图:
返回值
需要注意的是,getUserAction可能会有返回值,我们也要返回函数的执行结果,当immediate为fals的时候,因为使用了setTimeout,我们将func.apply(context, args)的返回值赋给变量,然后在return的时候会是undefined,所以我们只要在immediate为true的时候返回函数的执行结果。
1 | function debounce(func, wait, immediate) { |
取消
最后再来一个需求,希望能取消debounce函数,比如debounce的wait时间是10秒,immediate为true,在第一次触发后,下一次的触发将在10秒后了,如果有一个按钮,点击后,取消防抖,再去触发就又可以执行了。
1 | function debounce(func, wait, immediate) { |
这里是取消函数的使用方法
1 | var count = 1; |
效果图: