FunctionDebounce函数Debounce(去抖动):当一个事件连续触发时,如果一定时间内没有事件触发,事件处理函数只会执行一次。一旦事件被触发,延迟再次开始。如下图所示,当滚动事件持续触发时,句柄函数并没有被执行。当1000毫秒内没有触发scroll事件时,会延迟触发scroll事件。//防抖功能debounce(fn,wait){vartimeout=null;returnfunction(){if(timeout!==null)clearTimeout(timeout);varargs=argumentstimeout=setTimeout(()=>{fn.apply(this,args)},wait);}}//处理函数functionhandle(){console.log(Math.random());}//滚动事件window.addEventListener('scroll',debounce(handle,1000));functionthrottlefunctionthrottle(节流阀):当事件不断被触发时,保证事件处理函数在一定时间内只被调用一次。节流的常见解释就像打开水龙头的水,当阀门打开时,水就会流下来。有了勤俭节约的优良传统美德,我们应该关小水龙头。在一定时间间隔内逐滴。如下图所示,当连续触发scroll事件时,并没有立即执行handle函数,而是每1000毫秒执行一次handle函数。函数节流的实现方式主要有两种:时间戳和定时器。接下来用两个方法实现throttle~throttle代码(时间戳):varthrottle=function(func,delay){ varprev=Date.now(); returnfunction(){ varcontext=this; varargs=参数; varnow=Date.now(); if(now-prev>=delay){ func.apply(context,args); prev=Date.now(); } }}函数句柄(){ console.log(Math.random());}window.addEventListener('scroll',throttle(handle,1000));触发高频事件时,第一次会立即执行(绑定scroll事件的函数和实际触发事件的间隔一般大于延迟,如果你坚持1000以内加载网页毫秒,去如果我滚动网页,我做不到o(╥﹏╥)o),而且无论事件触发频率如何,每个延迟时间只执行一次。Throttle油门代码(定时器)://Throttle油门代码(定时器):varthrottle=function(func,delay){vartimer=null;if(!Timer){timer=settimeout(function(){func.apply(context,args);timer=null;},delay);}}FunctionHandle(){console.log(mth.random());}}window.addEventListener('scroll',throttle(handle,1000));当事件被触发时,我们设置一个计时器。再次触发事件时,如果定时器存在,则延迟时间过后才会执行。定时器执行执行函数并清除定时器,以便可以设置下一个定时器。第一次触发事件时,函数不会立即执行,而是延迟秒后执行。那么不管事件触发的频率如何,每个延迟时间只执行一次。最后一次停止触发后,由于定时器的延迟,函数可能会再次执行。可以同时使用时间戳或计时器进行节流。更准确地说,可以使用时间戳+定时器,在第一次触发事件时立即执行事件处理函数,在最后一次事件触发后执行一次事件处理函数。//Throttle节流代码(时间戳+定时器):varthrottle=function(func,delay){vartimer=null;varstartTime=Date.now();返回函数(){varcurTime=Date.now();varremaining=delay-(curTime-startTime);变量上下文=这个;var参数=参数;清除超时(计时器);如果(剩余<=0){func.apply(上下文,args);startTime=Date.now();}else{timer=setTimeout(func,剩余);}}}functionhandle(){console.log(Math.random());}window.addEventListener('scroll',throttle(handle,1000));使用开始时间startTime,当前时间curTime和delay内部节流计算剩余时间的函数。当remaining<=0时,表示应该执行事件处理函数(保证事件第一次触发时能立即执行事件处理函数,每隔延迟时间执行一个事件处理函数)。如果时间还没有到,则设置为在剩余时间后触发(保证在上次触发事件后可以再次执行事件处理函数)。当然,如果在remaining期间再次触发事件,则取消当前定时器,重新计算aremaining来确定当前状态。总结功能防抖:将多个操作合并为一个操作。原理是维护一个定时器,规定延时时间后触发该功能,但如果在延时时间内再次触发,则取消之前的定时器并重新设置。这样,只能触发最后一个动作。函数节流:让函数在一定时间内只触发一次。原理是通过判断是否到一定时间来触发函数。区别:无论事件触发频率如何,函数节流都会保证在指定时间内执行一次真正的事件处理函数,而函数防抖只会在最后一次事件后触发一个函数。比如在页面无限加载的场景下,我们需要用户在滚动页面的时候每隔一段时间发送一次Ajax请求,而不是在用户停止滚动页面的时候去请求数据。这样的场景适合使用节流技术。
