• 函数的节流和函数的防抖


    出现原因

    某些事件,如mousemove、scroll等是会不断触发,如果对应处理函数中有执行DOM操作、加载资源的行为,那很有可能会导致浏览器卡顿、崩溃等
    目前主流的解决方法为函数节流与函数防抖

    函数节流

    思想

    当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时

    操作

    1.第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码
    2.当第二次调用该函数时,清除前一次的定时器并重新设置
    3.如果前一个定时器已经执行过了,清除操作并不会产生什么影响
    4.如果前一个定时器尚未执行,上述操作就是将其替换为一个新的定时器

       method参数为实际执行的函数
       args为要传递的参数数组
       contex参数为执行环境 */
    function throttle(method,args,context){ 
        clearTimeout(method.tId);
        method.tId=setTimeout(function(){
            method.apply(context,args);
        },200);
    }
    
    function move(){
        console.log("xxx")
    }
    document.querySelector("#target").οnmοusemοve=function(){
        throttle(move);
    }

    如果我们不进行节流,那么鼠标在target元素上做一次滑行就会执行多次move函数,而节流后move函数执行数量明显变少

    VUE中使用:

    <template>
     <div>
      <input type='text' v-model='value' @keydown = "hangleChange">
     </div>
    </template>
    
    <script>
    function debounce(func, wait=1000){ //可以放入项目中的公共方法中进行调用(鹅只是省事)
     let timeout;
     return function(event){
      clearTimeout(timeout)
      timeout = setTimeout(()=>{
       func.call(this, event)
      },wait)
     }
    }
    export default{
     name:'',
     data(){
      return{
       value:''
      }
    },
     methods:{
      hangleChange:debounce(function(e){
       console.log(this.value)
      })
     }
    }
    </script>

    局限

    如果鼠标一直滑动,那么move方法永远不会执行,这时候就需要函数防抖

    函数防抖

    思想

    预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,在这段事件内新的调用动作都将无效,然后进入下一个新周期

    /* 一个封装节流操作的函数
       method参数为实际执行的函数
       wait参数为时间间隔
       args为要传递的参数数组
       contex参数为执行环境 */
    function debounce(method,wait,args,context){ 
        if(!method.start){
            method.start=new Date();
        }
        var now=new Date();
        if(now-method.start>=wait){
            method.apply(context,args);
            method.start=now;
        }
    }
    
    document.querySelector("#target").οnmοusemοve=function(){
        debounce(move,2000);
    }

    采用函数防抖后,只要鼠标在target上滑动,每2秒执行一次move函数

    VUE中使用

    <template>
     <div class="scroll" ref="previewText" @scroll.passive="fnScroll">
    </template>
    <script>
     export default{
      name:'globalHospot',
      data(){
        return{
          count:0,
          fnScroll:() =>{}
        }
      },
      methods: {
        fnHandleScroll (e) {
          console.log('scroll触发了:' + this.count++, new Date())
        },
        fnThrottle(fn, delay, atleast){  //节流函数
          let timer = null;
          let previous = null;
          return function(){
            let now = +new Date()
            if(!previous) previous = now;
            if(atleast && now - previous > atleast){
              fn();
              previous = now;
              clearTimeout(timer)
            }else{
              clearTimeout(timer)
              timer = setTimeout(()=>{
                fn();
                previous = null
              },delay)
            }
          }
        }
      },
      created(){
        this.fnScroll = this.fnThrottle(this.fnHandleScroll, 1000)  //刚创建时执行
      },
    }
    </script>
  • 相关阅读:
    C++ Primer Plus章节编程练习(第十章)
    Bezier曲线
    C++静态持续变量
    计算机图形学之三维图形变换
    计算机图形学之二维图形变换
    C++ Primer Plus章节编程练习(第七章)
    C++中的指针与const
    Java 输入输出流
    Java Fx 画圆环
    注册事件及事件处理
  • 原文地址:https://www.cnblogs.com/hy96/p/11947099.html
Copyright © 2020-2023  润新知