【性能优化】函数的防抖与节流

函数防抖

用手风琴案例演示,做防抖优化前和优化后的区别

简易手风琴案例(防抖优化前 )

图片资源地址:https://github.com/jiang-zi/Optimize-anti-shake-/tree/master/images

    <style>
      ul {
        list-style: none;
      }

      * {
        margin: 0;
        padding: 0;
      }

      div {
        width: 1200px;
        height: 400px;
        margin: 50px auto;
        border: 1px solid red;
        overflow: hidden;
      }

      div li {
        width: 240px;
        height: 400px;
        float: left;
        transition: all 500ms;
      }

      div ul {
        width: 1200px;
      }
    </style>
  </head>

  <body>
    <div id="box">
      <ul>
        <li>
          <a href="#">
            <img src="./images/1.jpg" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="./images/2.jpg" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="./images/3.jpg" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="./images/4.jpg" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="./images/5.jpg" alt="" />
          </a>
        </li>
      </ul>
    </div>
  </body>
  <script>
    //1.获取元素
    let liList = document.querySelectorAll('#box li')
    let box = document.querySelector('#box')

    //2.注册事件
    //2.1 鼠标移入
    for (let i = 0; i < liList.length; i++) {
      liList[i].onmouseenter = function () {
          //3.排他思想修改宽度: 我自己800px,其他人100px
          for (let j = 0; j < liList.length; j++) {
            if (i === j) {
              liList[j].style.width = '800px'
            } else {
              liList[j].style.width = '100px'
            }
          }
      }
    }

    //2.2 鼠标移出父盒子
    box.onmouseleave = function () {
      //3.设置每一个li元素宽度240
        for (let i = 0; i < liList.length; i++) {
          liList[i].style.width = '240px'
        }
    }
  </script>

结论 : 做函数防抖优化前,多次移入手风琴区域会出现抖动感。用户体验极其不好,还有内存资源得浪费。

解决方法 : 函数防抖

什么是函数防抖 : 间隔时间内 多次触发事件,以最后一次为准

函数防抖思路 :

  1. 声明一个变量存储定时器id
  2. 每一次触发事件的时候,先清除上一次的定时器,以本次为准
  3. 开启定时器,间隔时间之后再触发事件处理函数
    此时只要用户在这个间隔时间之内触发了其他事件,那么上一次的定时器就会被清除
    //防抖第一步:声明变量存储定时器id
    let timeID = null

    //2.注册事件
    //2.1 鼠标移入
    for (let i = 0; i < liList.length; i++) {
      liList[i].onmouseenter = function () {
        //防抖第二步: 每一次触发事件的时候,都要把上一次的定时器给移除。 以最后一次为准
        clearTimeout(timeID)
        //防抖第三步:每一次触发事件的时候,先不触发。开启定时器,间隔时间之后再触发
        timeID = setTimeout(function () {
          //3.排他思想修改宽度: 我自己800px,其他人100px
          for (let j = 0; j < liList.length; j++) {
            if (i === j) {
              liList[j].style.width = '800px'
            } else {
              liList[j].style.width = '100px'
            }
          }
        }, 300)
      }
    }

    //2.2 鼠标移出父盒子
    box.onmouseleave = function () {
      //3.设置每一个li元素宽度240
      clearTimeout(timeID)
      timeID = setTimeout(function () {
        for (let i = 0; i < liList.length; i++) {
          liList[i].style.width = '240px'
        }
      }, 300)
    }

函数节流

什么是函数节流 : 间隔时间内函数只被触发一次

函数节流作用: 降低高频事件的触发频率

  高频事件: 触发频率很高的事件  如 : onmousemove  onscroll

函数节流思路:

  1. 声明变量存储本次触发的时间time
  2. 每一次触发的时候, 使用 当前时间 - time,判断两次间隔是否超过 节流时间
    超过: 触发,并且存储本次触发时间。
    不超过:不触发

示例 :

      //节流第一步: 存储变量记录触发时间
      let time = null
        
      let i = 1
      //高频事件:鼠标移动
      window.onmousemove = function () {
        //节流第二步: 判断两次间隔是否超过 节流时间
        let currentTime = Date.now()
        if( currentTime - time >= 10000 ){
            i++
            console.log('鼠标移动触发次数:' + i )
            //节流第三步: 存储本次触发时间
            time = currentTime
        } 
      }
    //   let j = 1
      //高频事件:鼠标滚动
    //   window.onscroll = function(){
    //     j++
    //     console.log('鼠标滚动条触发次数:' + j )
    //   }

函数的防抖与节流总结

函数防抖及应用场景:

  1. 函数防抖 : 间隔时间 内多次触发事件以最后一次为准
  2. 应用场景 : 鼠标移入/移出 、 键盘输入框

函数节流及应用场景:

  1. 函数节流 : 间隔时间 内事件只会触发一次
  2. 应用场景 : 高频事件 鼠标移动 鼠标滚动条

防抖与节流异同点 :

相同点: 都是为了优化函数执行频率,提高网页性能

不同点:

  • 防抖: 优化‘用户主动‘触发的事件, 多次触发以最后一次为准
  • 节流: 优化‘事件本身’执行的频率, 间隔时间只执行一次

搜索框防抖案例

    <input type="text" placeholder="请输入搜索内容" />
    <script>
      let timeID = null

      document.querySelector('input').oninput = function () {

        //清除上一次定时器,以本次为准
        clearTimeout(timeID)
        //开启本次防抖定时器
        /* 
        细节:定时器中的this,默认指向window
        如果定时器函数是箭头函数,则会访问上一次this : 事件源
        */
        timeID = setTimeout(()=>{
            console.log(this.value)
        },300)

      }
    </script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疆子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值