平时咱们本身在开发过程当中可能须要监听窗口的大小(resize等)来调节样式,或者是根据鼠标移动(mousemove等)来执行相应的方法,以及键盘按键(keyup等)事件。可是这里会产生一个问题——频繁改变窗口大小和移动鼠标会致使前端页面被频繁渲染,有时候可能致使页面崩溃。页面渲染过程当中也就是dom被操做的过程,而dom操做越频繁,对前端的性能影响就越大,前端性能也越差,因此大神们就总结除了函数防抖和节流这两种解决页面被过渡渲染致使性能低下的问题。 因此在此记录下以供未来复习,同时也可以经过这些文章来了解到本身哪些时间段学习过什么内容。前端
代码实现java
/*
*fn:要防抖的函数
*wait:要等待的时间
*immediate:是否马上执行fn函数
*/
function debounce(fn,wait,immediate){
let timer=null;
let _debounce=function(){
//判判定时器是否存在,存在即删除定时器
timer&&clearTimeOut(timer);
//是否马上执行
if(immediate){
//定时器不存在时,才回去执行函数
!timer&&fn.apply(this,...arruments)
timer=setTimeOut(()={
timer=null;
//过了await时间后,fn才能够被再次执行
},await)
}else{
timer=setTimeOut(()=>{
//过了await时间后,再次设置的定时器才不会被清除
timer=null;
fn.apply(this,...arguments);
//arguments为调用fn函数传入的参数
},await)
}
}
//取消
_debounce.cancel=()=>{
timer=null;
clearTimeOut(timer);
}
return _debounce;
}
//应用
document.onmousemove=debounce(function(e){
console.log("鼠标移动了");
console.log(new Date().getUTCSeconds());
console.log(e);//e是事件对象,
},300,true);
复制代码
输出结果以下: git
代码实现:github
function throtle(fn,await){
let timer=null;
let previousTime=0;
let _throtle=()=>{
let now=+new Date();//获取当前时间戳
let remain=now-previousTime
if(remain>await){
//下面的代码只会在第一次触发时执行(或者是间隔时间超过await后再次执行)
if(timer){
//清除定时器
clearTimeOut(timer);
timer=null
}
//此时now不等于+new Date()
previousTime=+new Date();//当前时间,使用+获取当前时间戳
fn.apply(this,...arguments);
}else if(!timer){//避免添加多个定时器
timer=setTimeOut(()=>{
timer=null;
previousTime=+new Date();//当前时间
fn.apply(this,...arguments);
},remain);
}
}
_throtle.cancel=()=>{
timer=null;
clearTimeOut(timer);
previousTime=0;
}
return _throtle;
}
复制代码
参考连接:
一、一个合格的中级前端工程师必需要掌握的 28 个 JavaScript 技巧
二、函数防抖
三、javaScript专题之跟着underscore学防抖
四、javaScript专题之跟着underscore学节流前端工程师