• 函数防抖与节流


    1.为什么会有函数的防抖与节流及使用场景

    在进行窗口的resize、scroll,输入框内容校验或者向后端发起ajax等操作时,
    如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。
    此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时又不影响实际效果。

    2.函数防抖与函数节流的概念及实现原理

    函数防抖(debounce):
      当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

    函数节流(throttle):
      当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

    函数防抖 原理:
      闭包 + 计时器

    函数节流 原理:
      闭包 + 时间戳
      

    3.函数防抖代码实现

    //注意:事件处理函数的this指向必须要指向事件对象,所以,以下代码中出现了改变函数this指向的问题
    <body> <input type="text" id="txt"> </body> <script> var txt = document.getElementById("txt");
      //函数防抖 function debounce(fn, delay) {
    //this指向window // console.log("0" + this); var timer = null; return function () { //this指向事件对象input,记录this到context中 // console.log(this); var context = this; //arguments为实参的个数 var args = arguments; //清除计时器 clearTimeout(timer); //计时器中的this指向window,而事件处理函数中的this要指向事件对象, timer = setTimeout(function () { //this指向window // console.log("3" + this); //改变fn的this指向,使其指向事件对象 //方法1: fn.apply(context, args); //方法2 // fn.call(context); }, delay); } } //事件处理函数 function handle() { console.log(Math.random()); //在throttle函数中改变该函数的this指向,是该函数this指向事件对象。如果不在throttle函数中改变this的指向,则该函数的this指向window // console.log(this); } txt.oninput = debounce(handle, 1000); //第一次事件触发,则先执行debounce函数,在执行闭包函数,一步一步执行,第一次以后的每次事件触发都是直接执行debounce函数中的闭包函数 </script>

    4.函数节流代码的实现

    //注意:事件处理函数的this指向必须要指向事件对象,所以,以下代码中出现了改变函数this指向的问题
    <body>
        <input type="text" id="txt">
    
    </body>
    <script>
        var txt = document.getElementById("txt");
         //函数节流
        function throttle(fn, duration) {
            //获取开始时间(事件戳)
            var begin = new Date();
            return function () {
                var context = this;
                var args = arguments;
                //获取当前时间
                var current = new Date();
                console.log(begin);
                console.log(current);
                console.log(current - begin);
                if (current - begin >= duration) {
                    fn.apply(context, args);
                    begin = current;
                }
    
            }
        }
        //事件处理函数
        function handle() {
            console.log(Math.random());
            //在throttle函数中改变该函数的this指向,是该函数this指向事件对象。如果不在throttle函数中改变this的指向,则该函数的this指向window
            // console.log(this);
        }
    
        txt.oninput = debounce(handle, 1000,34);
        //第一次事件触发,则先执行debounce函数,在执行闭包函数,一步一步执行,第一次以后的每次事件触发都是直接执行debounce函数中的闭包函数
    </script>

    5.函数节流与函数防抖结合代码实现

    //注意:事件处理函数的this指向必须要指向事件对象,所以,以下代码中出现了改变函数this指向的问题
    <body>
        <input type="text" id="txt">
    
    </body>
    <script>
        var txt = document.getElementById("txt");
     //函数节流与防抖结合
        function throttle(fn, delay,duration) {
            var timer = null;
            //获取开始事件(事件戳)
            var begin = new Date();
            return function () {
                var context = this;
                var args = arguments;
                //获取当前时间
                var current = new Date();
                clearTimeout(timer);
                //节流
                if(current - begin >= duration){
                    fn.apply(context,args);
                    begin = current;
                }else{
                   //防抖
                    timer = setTimeout(function () {
                    //this指向window
                    // console.log("3" + this);
    
                    //改变fn的this指向,使其指向事件对象
                    //方法1:
                    fn.apply(context, args);
    
                    //方法2
                    // fn.call(context);
                }, delay);
    
                }
    
            }
        }
        
        //事件处理函数
        function handle() {
            console.log(Math.random());
            //在throttle函数中改变该函数的this指向,是该函数this指向事件对象。如果不在throttle函数中改变this的指向,则该函数的this指向window
            // console.log(this);
        }
    
        txt.oninput = debounce(handle, 1000500);
        //第一次事件触发,则先执行debounce函数,在执行闭包函数,一步一步执行,第一次以后的每次事件触发都是直接执行debounce函数中的闭包函数
    </script>
  • 相关阅读:
    Android AlertDialog警告对话框实现
    Android状态栏通知Status Bar Notification
    Android spinner控件的实现
    Winform之UI后台线程
    Winform之自定义控件
    WebForm原理,aspx服务器端与客户端源码比较
    IHttpModule之闲扯
    [算法]方正面试题:N×N矩阵螺旋打印输出
    DOTA版设计模式——工厂方法
    Window服务
  • 原文地址:https://www.cnblogs.com/SRH151219/p/10368959.html
Copyright © 2020-2023  润新知