JavaScript 防抖与节流

JavaScript 防抖与节流

  • 前言
  • 防抖
  • 节流
  • 区别

前言

DOM 事件中有很多高频操作,比如 onscroll 滚动监听,input 输入值监听,获取屏幕尺寸 resize 等。在实际应用场景中还有防止按钮多次点击。那么怎么减少高频事件的执行和阻止按钮多次点击昵?最好的方案就是防抖与节流。

防抖

上一个定时器没有执行完,直接清除定时器,开启下一轮定时器。将多个操作优化为只在最后一次执行。
使用场景:用户输入。输入完成之后做一次校验即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <title>React App</title>
</head>
<body>
<input type="text" id="input">
</body>
<script>
    function sayHi(ages) {
     
        console.log(ages);
    }
   function debounce(fn,time,immediate) {
     
       var timer = null ;
       var context = this;
       var callNow = immediate;
       return function(...args){
     
          //立即执行
	      if (immediate) {
     
	           fn.apply(context, args);
	           callNow = false;
	       }
           //当有定时器时,先将定时器清掉
          if(timer) {
     clearTimeout(timer)}
          //然后开启下一轮定时器
          timer = setTimeout(()=>{
     
                  fn.apply(context,arg);              
              },time)
          }
   }
    var input = document.getElementById('input');
    input.addEventListener('input', debounce(sayHi,1000,'防抖')); // 防抖
</script>
</html>

节流

上一个定时器没有执行完,直接返回,等待执行完成之后,再开启下一轮定时器。
使用场景: 滚动条事件 或者 resize 事件,通常每隔 100~500 ms执行一次即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <title>React App</title>
</head>
<body>
<input type="text" id="input">
</body>
<script>
    function sayHi(ages) {
     
        console.log(ages);
    }
   function throttle(fn,time,immediate) {
     
       var timer = null;
       var context = this;
       var callNow = immediate;
       return function(...arg){
     
	       if (callNow) {
     
	            fn.apply(context, args)
	            callNow = false
	        }
          //只有当上一轮定时器走完才开启下一轮
          if(!timer){
     
              timer = setTimeout(()=>{
     
                  fn.apply(context,arg);
                  clearTimeout(timer);
                  timer = null;
              },time)
          }
       }
   }
    var input = document.getElementById('input');
    input.addEventListener('input', throttle(sayHi,500,'节流')); // 节流
</script>
</html>

区别

不管是防抖还是节流,其根本原理都是通过定时器来阻止高频事件。区别在于:

  1. 防抖只是为了防止多个定时器同时执行造成的抖动或者卡顿。所以在没有开启下一轮定时器时,都需要先将已存在的定时器清掉。这样就不会同时存在多个定时器。
  2. 节流是在防抖的基础上对定时器时间有更高的要求。必须等到上一轮定时器走完才可开启下一轮定时器。
  3. 假设定时器为 3s,防抖是走到1s,2s的时候把定时器清除,继续开启下一轮定时器,继续走1s,2s,,。节流是走到 1s,2s 的时候直接返回。非要走完1s,2s,3s 方可开启下一轮定时器。
  4. 防抖:1,2 || 1,2,3 || 1 || 1,2,3;
    节流:1,2,3 || 1,2,3 || 1,2,3 || 1,2,3。

你可能感兴趣的:(前端面试)