js原生实现防抖节流

共同点:都用到了setTimeout定时器,都是在指定时间间隔后执行函数,都是为了解决数据时时变化而时时请求导致性能差的问题

区别:防抖在指定时间间隔里再次调用函数,会清除定时器,重新计时,直到在最新的计时时间间隔里没有调用函数,才会执行定时器里的函数。
而节流会在指定时间间隔后会执行一次函数,不会清除定时器而重新计时

防抖缺点:当用户在指定时间间隔里一直操作,那么setTimeout会一直重新计时函数永远不会执行
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

节流缺点:如果用户一直操作,那么setimeout里的函数会在指定时间间隔后都会执行一次,如此反复
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。

1. 防抖 (在一定时间间隔内高频触发 只执行最后一次)

防抖策略(debounce)是当事件被触发后,延迟n秒后再执行回调,如果在这n秒内事件又被触发,则重新计时。

作用: 高频率触发的事件,在指定的单位时间内,只响应最后一次,如果在指定的时间内再次触发,则重新计算时间。
1.1防抖的应用场景
1.搜索框等按钮避免用户点击太快,以致于发送了多次请求,需要防抖;
2.手机号、邮箱验证
3.调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖;
4.文本编辑器实时保存,当无任何更改操作一秒后进行保存。
以监听input的值举例:

// 防抖
var input = document.getElementById('input')
input.addEventListener('input', debounce(handle, 1000))
function debounce(fn,delay = 20){
	var timer = null;
	return function(...args){
		if(timer){
			clearTimeout(timer)
		}
		timer = setTimeout(()=>{
			fn.apply(this,args)
		}, delay)
	}
}
function handle(e){
	console.log(e.target.value)
}

2. 节流 (在一定时间间隔内高频触发 只触发一次)

节流策略(throttle),控制事件发生的频率,如控制为1s发生一次,甚至1分钟发生一次。与服务端(server)及网关(gateway)控制的限流 (Rate Limit) 类似。
作用: 高频率触发的事件,在指定的单位时间内,只响应第一次

2.1 节流的应用场景
1.鼠标连续不断地触发某事件(如点击),单位时间内只触发一次;
2.高频事件:鼠标移动 mousemove 、页面尺寸缩放 resize 、滚动条滚动 scroll 等
3.监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断。例如:懒加载;
scroll、mousehover、mousemove等触发频率高的时候
4.浏览器播放事件,每个一秒计算一次进度信息等。

// 节流
var input = document.getElementById('input')
input.addEventListener('input', throttle(handle, 200))
function throttle(fn,delay = 20){
	let timer = null;
	return function(...args){
		if(timer){
			return;
		}
		timer = setTimeout(()=>{
			fn.apply(this,args)
			timer = null
		},delay)
	}
}
function handle(e){
	console.log(e.target.value)
}
  <style>
    .box,
    .box2 {
      width: 100px;
      height: 100px;
      line-height: 100px;
      font-size: 28px;
      background-color: pink;
      text-align: center;
      cursor: pointer;
      margin-top: 20px;
    }
  </style>

  <body>
  <div class="box">1</div>
  <div class="box2">1</div>

  <script src="../lodash.min.js"></script>
  <script>
    /*
    防抖节流
    1. 防抖(debounce)
      所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间
      使用场景:
        1.搜索框
        2.手机号、邮箱验证输入检测
    2. 节流(throttle)
      所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数
      使用场景:
        1.高频事件:鼠标移动 mousemove 、页面尺寸缩放 resize 、滚动条滚动 scroll 等

    */

    // 利用防抖实现性能优化
    // 需求:鼠标在盒子上移动,里面的数组就会变化 +1
    const box = document.querySelector('.box');
    let i = 1;
    function mouseMove() {
      box.innerHTML = i++;
      // 如果里面存在大量消耗性能的代码,如 dom操作、数据处理,可能造成卡顿
    }
    // 添加事件
    // box.addEventListener('mousemove', mouseMove)

    // 利用 lodash库实现防抖 - 500毫秒之后采取 +1
    // 语法: _.debounce(fun,时间)
    // box.addEventListener('mousemove', _.debounce(mouseMove, 500))

    /* 
    手写防抖函数
    防抖的核心就是利用定时器(setTimeout)来实现
    1.声明一个定时器 变量
    2.先判断是否有定时器,如果有 清除以前的定时器
    3.如果没有定时器则开启定时器,记得存到变量里面
    4.在定时器里面调用要执行的函数
    */
    function debounce(fn, time) {
      let timer = null;
      return function (...args) {
        // 清除定时器
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
          fn.apply(this, args)
        }, time);
      }
    }
    box.addEventListener('mousemove', debounce(mouseMove, 500))


    // 节流
    // 需求:鼠标在盒子上移动,不管移动多少次,每隔500ms才 +1
    const box2 = document.querySelector('.box2');
    let i2 = 1;
    function mouseMove2() {
      box2.innerHTML = i2++;
      // 如果里面存在大量消耗性能的代码,如 dom操作、数据处理,可能造成卡顿
    }
    // 语法: _.throttle(fun,时间)
    // box2.addEventListener('mousemove', _.throttle(mouseMove2, 500))
    /*
    手写节流函数
    节流的核心就是利用定时器(setTimeout)来实现
    1.声明一个定时器 变量
    2.先判断是否有定时器,如果有 不开启新的定时器
    3.如果没有定时器则开启定时器,记得存到变量里面
    4.在定时器里面调用要执行的函数,在定时器里面要把定时器清空
    */
    function throttle(fn, time) {
      let timer = null;
      return function (...args) {
        if (timer) return;
        timer = setTimeout(() => {
          fn.apply(this, args)
          // 定时器里无法清除定时器
          timer = null;
        }, time);
      }
    }
    box2.addEventListener('mousemove', throttle(mouseMove2, 500))
  </script>
</body>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值