手写节流跟防抖,进行封装

在准备js面试题时,遇到了许多知识盲区,或是已经遗忘的知识,所以来写一下博客,记录自己的成长,同时查漏补缺

防抖跟节流是js面试时经常会考的面试题,什么是防抖,将多次高频操作优化为只在最后一次操作执行,来,直接进入案例

监听一个输入框,文字变化后触发change事件

<input type="text" class="input">

直接用keyup事件,模拟触发change事件

const input = document.querySelector('.input')

添加键盘事件
 input.addEventListener('keyup', function() {
      console.log(input.value);    
})

当我们输入的时候

 就会不断的触发change事件,如果我们是一边输入,一边网络请求,那几秒钟下来得发送多少请求,我想要的是,用户输入结束或暂停0.5秒或一秒后才会触发change事件,如果不停的输入那就不会触发,这就是防抖的机制,将多次高频操作优化为只在最后一次操作执行

 修改一下代码

 //创建一个变量
    let timer = null
    //添加键盘事件
    input.addEventListener('keyup', function() {
      if(timer) {
        //如果定时器存在,就清除定时器,然后让timer等于新触发的这个定时器
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        console.log(input.value);
        timer = null
      },1000)
      
    })

 接下来将防抖给封装成一个函数

   //如果delay不传入,默认值是500毫秒
    function debounce(fn, delay = 500) {
      let timer = null
      let args = arguments
      return function() {
        if(timer) {
          clearTimeout(timer)
        }
        timer = setTimeout(() => {
          fn.apply(this, args)
          timer = null
        }, delay)
      }
    }

使用debounce函数来执行看看

input.addEventListener('keyup', debounce(function() {
      console.log(this.value);
    }))

 效果是一样的,说明没毛病

 接下来说节流,节流,是限制持续触发的事件,让该事件,每隔一段时间,只执行一次,看代码

 //定义一个函数,这个函数来改变body的背景颜色,随机改变
    function bgc() {
      let r = Math.random() * 255
      let g = Math.random() * 255
      let b = Math.random() * 255
      document.body.style.backgroundColor = `rgb(${r},${g},${b})`
    }
    //resize监听浏览器屏幕的改变
    window.addEventListener('resize',function() {
      //屏幕改变时就调用bgc函数
      bgc()
    })

看效果

 我不想让它一直触发,我想在我改变屏幕的时候,颜色每隔500毫秒或者一千毫秒才改变一次,在单位时间间隔后事件才触发,其实这就是节流的机制,节流有两种做法,一种是利用时间戳,一种是利用定时器,我这里用定时器演示

将代码改进一下

 //定义一个函数,这个函数来改变body的背景颜色,随机改变
    function bgc() {
      let r = Math.random() * 255
      let g = Math.random() * 255
      let b = Math.random() * 255
      document.body.style.backgroundColor = `rgb(${r},${g},${b})`
    }
    //resize监听浏览器屏幕的改变
    // window.addEventListener('resize',function() {
    //   //屏幕改变时就调用bgc函数
    //   bgc()
    // })
    
    //定义一个变量,这变量是节流的开关
   let timer = null

    window.addEventListener('resize',function() {
      if(timer) {//如果存在定时器,就返回
        return
      }
      timer = setTimeout(() => {
        bgc()
        timer = null //同时让定时器清空,不然timer会一直存在,
        //事件改变时,就一直只在if那里执行,下面的语句不会执行
      }, 1000)//一秒后触发
    })

 看改过后的效果

 接下来我们封装一个节流函数

    //默认间隔时间为500毫秒
    function throttle(fn, delay = 500) {
      let timer = null
      let args = arguments
      return function() {
        if(timer) {
          return 
        }
        timer = setTimeout(() => {
          fn.apply(this, args)
          timer = null// 这句话很重要,一定要清空timer
        }, delay)
      }
    }

    // 使用一下看看
    window.addEventListener('resize', throttle(() => {
      bgc()
    }))

 

 每隔五百毫秒变化一次颜色,没毛病

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值