防抖
你尽管触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行,总之,就是要等你触发完事件 n 秒内不再触发事件,我才执行
解决两个问题:
this
的指向event
对象
var count = 1;
var container = document.getElementById('container');
function getUserAction(e) {
console.log(e)
container.innerHTML = count++;
//console.log(this) // 此时的this指向的window,本来应该是<div id="container"></div>
};
// container.onmousemove = getUserAction;
container.onmousemove = debounce(getUserAction,1000)
function debounce(func,wait){
var timeout
return function(){
// 修复this指向
var that = this
// 修复event对象
var args = arguments
//先清除掉之前的定时器
clearTimeout(timeout)
//设置定时器,wait秒之后执行
timeout = setTimeout(function(){
func.apply(that,args)
},wait)
}
}
需求1-立刻执行
不希望事件停止触发之后才执行,而是希望立刻执行函数,然后等到停止触发n秒之后,才可以重新执行。简单,只需要加一个判断,是不是立刻执行。
var count = 1;
var container = document.getElementById('container');
function getUserAction(e) {
console.log(e)
container.innerHTML = count++;
//console.log(this) // 此时的this指向的window,本来应该是<div id="container"></div>
};
// container.onmousemove = getUserAction;
container.onmousemove = debounce(getUserAction,1000,true)
function debounce(func,wait,immediate){
var timeout
return function(){
// 修复this指向
var that = this
// 修复event对象
var args = arguments
if(timeout) clearTimeout(timeout)
if(immediate){ // ->判断是不是立刻执行的
// 如果已经执行过,不再执行
var callNow = !timeout
timeout = setTimeout(function(){
timeout = null
},wait)
if(callNow) func.apply(that,args)
}else{
//设置定时器,wait秒之后执行
timeout = setTimeout(function(){
func.apply(that,args)
},wait)
}
// + return result // 111
}
}
/**
如果getUserAction有返回值的话,当immediate为false的时候,因为使用了定时器又不是立刻执行,我们需要将func.apply(that,args)的返回值赋给变量,最后return的时候,值是undefined,所以我们只在immediate为true的时候返回函数的结果
- var timeout
+ var timeout,result
- if(callNow) func.apply(that,args)
+ if(callNow) result = func.apply(that,args)
+ return result // 111
*/
需求2-取消防抖
function debounce(func, wait, immediate) {
var timeout, result;
var debounced = function () {
var context = this;
var args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) result = func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
return result;
};
debounced.cancel = function() {
clearTimeout(timeout);
timeout = null;
};
return debounced;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ZengXPang's blog!
评论