被问了无数次了
通常用于滚动事件,scroll,touchmove事件。在ms时间内只能执行一次,那我要特么怎么知道上一次函数有没有执行完毕。通过now - lastTime>ms得知。目前测试没有bug
function throttle(callback, ms){
var times;
var last = 0;
var outArgs = arguments
return function (){
var innerArgs = arguments
var now = +new Date();
if(now>last+ms){
// 超过节流时间,执行一次,并将上次执行时间戳更新。
last = now
callback.apply(this,[...innerArgs, ...[...outArgs].splice(2,)]);
}
}
}
通常用于resize,这个陌生,但是点击按钮添加防抖总听过了吧,为了防止某些脑残用户不断点击提交按钮,持续触发onclick事件,导致JavaScript报错。原生js实现方式,,这个特别简单。
function debounce(callback, ms){
var times;
var outArgs = arguments
return function (){
var self = this
var innerArgs = arguments
clearTimeout(times) // 如果你在某段时间之内再次触发,清除上一次触发的定时器,重新添加定时器。
times = setTimeout (function () {
callback.apply(self,[...innerArgs, ...[...outArgs].splice(2,)]);
},ms)
}
}
上述函数有两个非常有意思地点:
闭包垃圾回收机制,times属于返回函数引用地外部变量,这个时候外部变量被返回函数引用,导致无法触发JavaScript地垃圾回收机制,这样子,每次函数被调用,都会共享之前的timer变量,除非你将debounce函数重新执行一次,不然times变量依然是之前那个,垃圾回收机制被禁止触发,因为times变量地引用次数>0,
事件代理函数只接受一个未执行函数func,而不接受已执行函数。func(),同时接受返回的未执行函数,并为该函数提供event参数。
document.addEventListener('click',actionFunc(1,2,3)) // 无法触发事件代理模型
document.addEventListener('click',actionFunc) // 成功触发事件代理。