JS防抖
程序员文章站
2022-05-14 13:28:12
...
在前端开发的过程中,有时候我们需要对一些事件进行相应,但是,有时候,这些事件可能会十分频繁的触发。比如:
1、window 的 resize、scroll
2、mousedown、mousemove
3、keyup、keydown
为了解决这样的问题,一般会有两种方案来解决:
防抖和节流(debounce and throttle)
本篇将讲述第一种方案:防抖
防抖
防抖的原理就是,触发事件的回调函数会在事件被触发后的n毫秒后执行,假如在这n毫秒内,该事件再次被触发,那么就会以新的触发时间为准,n毫秒后执行。这样,就是当n毫秒内事件不再被触发的时候,该事件才会真正的执行。
例子:
防抖前:
var count = 1;
var container = document.getElementById('container');
function getUserAction() {
container.innerHTML = count++;
};
container.onmousemove = getUserAction;
防抖后:
function debounce(func, wait) {
var timeout;
return function () {
clearTimeout(timeout)
timeout = setTimeout(func, wait);
}
}
container.onmousemove = debounce(getUserAction, 1000);
this的问题
如果我们在最初的 getUserAction 函数中 console.log(this),输出的将会是container div, 但是如果使用了debounce,this将会丢失,指向window对象。这里我们需要修改代码使得this的指向不被改变。
function debounce(func, wait) {
var timeout;
return function () {
var context = this;
clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context)
}, wait);
}
}
* event的问题 *
如果我们在函数getUserAction中获取event对象,是可以获取到的:
function getUserAction(e) {
console.log(e);
container.innerHTML = count++;
};
但是如果在debounce函数中, 将会丢失event,只能打印出undefined。
我们可以将代码继续修改为:
function debounce(func, wait) {
var timeout;
return function () {
var context = this;
var args = arguments;
clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}