js:防抖和节流

导读:

js中的防抖和节流函数是前端面试考察的重点,近年来,不管是大厂还是小厂,防抖和节流都是几乎必被问到的点,而这两点对于js初学者来说是比较有难处的,所以本文主要提出我的理解和观点。

防抖:

防抖相当于什么呢,举个例子来说,我们在电脑中输入一串字符,如果我们的后台通过js拿到我们输入的字符信息,那么,你可能会写出这样的代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		
		<input type="text" id="input" />
		<script>
		
		 var input=document.getElementById("input");
		 function debounce(delay,value){
			setTimeout(function(){
				 console.log(value);
				 
			 },delay)
		 }
		 input.addEventListener('keyup',function(e){
			 debounce(1000,e.target.value);
		 } )
		 
		</script>	
	</body>
</html>

这段代码的目的就是为了打印我们每次输入的字符串。大家可以在你的浏览器里运行一下,效果大概是这样的

就是我输入haha 这每一个字母他都会给我打印,那么虽然我们最后肯定可以得到哈哈这个信息,但是,如果每一次输入的都要被打印,信息过大的话,对于浏览器和我们的电脑来说,都是一个负担,并且也没必要对吧,中间这些信息都是我们所不需要的,所以我们这里的方法是

在前一次任务执行还没有结束的时候,这个时候如果出现了下一次的任务,我们就把前一次的任务直接清理掉!

也就是说我输入h这个字母的时候,那么我下一秒之前,我输入了a,那么我们打印h这个字母的事件就该被清理掉!如果下一秒我没有做事情,那么就会打印ha 你想对不对?

也就是说在做下一件事情的之前,先把上一件事情清理掉!

那么我们不难写出下列的代码

 var input=document.getElementById("input");
		 function debounce(delay,value){
			 let timer=null;
			 clearTimeout(timer);//清理上一次的事件
		 timer=setTimeout(function(){
				 console.log(value);
				 
			 },delay)
		 }
		 input.addEventListener('keyup',function(e){
			 debounce(1000,e.target.value);
		 } )
		 

那么能实现我们的目标吗?很明显不能啊 这里的timer你清理的始终是一个null的值啊

每一次调用都是null,所以没有效果啊!!!

如何得到timer上一次的值呢?——使用闭包啊兄弟们!

闭包简易上理解就是函数里return 一个函数,他的好处就是防止全局变量污染,但是也容易造成变量泄露。我们这里要得到上次timer的值,我们就可以使用闭包!

var input=document.getElementById("input");
		 function debounce(delay){
			 let timer=null;
			 return function(value){
			 clearTimeout(timer);//清理上一次的事件
		    timer=setTimeout(function(){
				 console.log(value); 
			 },delay)
			 }
		 }
		 var hh=debounce(1000);
		 input.addEventListener('keyup',function(e){
			 hh(e.target.value);
		 } )

大家看这个 闭包,闭包里面的timer 除了刚开始是null,之后就不会是null了哈哈哈

因为闭包里面time清理的会是上一次的timer。我这样写大家是不是更容易理解呢?

 var input=document.getElementById("input");
		  let timer=null;
		 function debounce(delay){
			
			 return function(value){
			 clearTimeout(timer);//清理上一次的事件
		    timer=setTimeout(function(){
				 console.log(value); 
			 },delay)
			 }
		 }
		 var hh=debounce(1000);
		 input.addEventListener('keyup',function(e){
			 hh(e.target.value);
		 } )

我把timer放到外面 ,这样大家就理解了吧,因为闭包使得里面的timer得到的都能是上一次的,

所以你在一秒钟内如果输入了再多,你打印的都会是你最后停止输入前的那一个!

这个代码是成功的,大家可以实验啦!(*^▽^*)

 节流

节流我举个例子哈,大家玩英雄联盟的时候,回城这个操作,是不是你点了一次,然后他要过十秒就回到家,你中途如果离开了,再点回城,它就要重新十秒开始。又一个例子,英雄的技能只在规定的秒数之后触发

这就是节流的思想了,节流就是我这个事件,比如我2s一次,那么在2s之内你点1次也好,你点2次也好,你点213123次也好(夸张),我都只触发一次!!!

那么在上面的比如输入的时候,其实我输入第一个h的时候,如果用节流,那么它就会在2

s之内给我打印h,如果在这2s内输入其他的,它才不管呢!

我们这里有一个例子:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		
	<button id="button">你点啊啊</button>
	
	
	
	<script>
	function thro(func,wait){
		let timer;
		return function(){
			if(!timer){
		      timer=setTimeout(function(){
				func()
				//办理玩了之后后面不办理了
				timer=null;
			},wait)
		}
		}
	}
	function fn(){
		console.log(123);
	}
	document.getElementById('button').onclick=thro(fn,2000);

这就是一个典型的使用闭包回流的例子!

达到的效果就是

 我在2秒之内点了2次按钮,他结果只出现一次123,我2s之后再点,它再出现1次123

这里的核心代码就在于使用闭包得到上次的timer的值,我们点了,触发这个事件,那么timer的值就不是null了,所以我们执行,当我们在执行这次2s的任务时候,我们重新吧timer变成null,这样就保证timer在这2s之内一直是null,所以你无论怎么点!他都不会触发打印事件了,只有这两秒事件之后,下一次点击,又来这样的节奏.......

这就是我理解的防抖节流,路漫漫其修远兮!感谢你的观看!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值