zoukankan      html  css  js  c++  java
  • 函数的节流和抖动

    函数的节流

    函数节流的原因

    DOM操作操作比非DOM操作需要更多的内存和CPU时间
    比如 onresize事件处理程序DOM操作,高频率会让浏览器崩溃,解决这个问题可以用定时器对该函数进行节流 

     函数节流基本思想

     每隔一段时间执行, 比如第一次调用函数,创建一个定时器,在指定时间隔执行代码,第二次调用函数。会清除前一次的定时器并设置另一个

    let processor = {
        timeoutId: null,
        performProcessing: function (){
            console.log('实际执行代码')
        },
        process: function(){
            clearTimeout(this.timeoutId);
            let that = this   // setTimeout 函数环境总是window,所以保存this的引用以方便以后使用
            this.timeoutId = setTimeout(function(){
            that.performProcessing()
            }, 100)
        }
    
    }
    processor.process()
     

    在这段代码创建叫做processor对象,这个对象还有两个方法: process()和 performProcessing()
     前者初始化任何处理必须调用的,后者则实际进行应完成的处理。当调用process(),第一步是阻止之前的调用被执行
    然后创建一个新的定时器调用performProcessing()。时间间隔100ms,这表示最后调用process()之后至少100MS才会调用performProcessing()

     function throttle(method, context){
        clearTimeout(method.tId)
        method.tId = setTimeout(function(){
            method.call(context);
        }, 100)
       }

    throttle函数接受两个参数: 要执行的函数以及在在哪个作用域执行
    上面这个函数首先清除之前的设置的任何定时器。定时器ID是存储在函数tId属性中的第一次把方法传给throttle(),的时候这个方法
    可能不存在。接下来创建一个新的定时器,并将其ID储存在方法的tId属性中,定时器代码使用call()
    来确保方法在适当的环境中执行。 如果没有给出第二个参数,那么就在全局作用中内执行该方法

    实际案例

      
        /** 节流在resize事件中最常用的
        */
        window.onresize = function(){
           let div = document.getElementById("myDiv");
           div.style.height = div.offsetWidth + "px" 
        }
     function resizeDiv(){
           let div = document.getElementById("myDiv");
           div.style.height = div.offsetWidth + "px" 
        }
         window.onresize = function(){
          throttle(resizeDiv);
        }

    调整大小功能被放入一个叫做resizeDiv()的单独函数中。然后onresize事件处理程序调用throttle()
    并传入resizeDiv函数,而不是直接调用resizeDiv()。只要代码是周期执行的,都应该使用节流,但是你不能控制请求执行的速率。
    这里展示的throttle()函数用了100ms作为间隔,可以根据需要修改。

    例如

    电梯等第一个人进来之后,5秒后准时运作,不等待,若5秒内还有人进来,也不重置。

    使用场景

    resizetouchmove移动DOM,上拉列表加载数据等。

    <!DOCTYPE html>
    <html>
    <head>
        <title>加入节流-定时器</title>
    </head>
    <body>
        <div>
            加入节流-定时器:<input type="text" id="throttle"/>
        </div>
        <script>
            window.onload = () => {
                function ajax (data) {
                    console.log(new Date().toLocaleTimeString() + ' - ' + data)
                }
    
                function throttle (fn, delay) {
                    return args => {
                        if (fn.id) return
    
                        fn.id = setTimeout(() => {
                            fn.call(this, args)
                            clearTimeout(fn.id)
                            fn.id = null
                        }, delay)
                    }
                }
    
                const throttleAjax = throttle(ajax, 1000)
    
                document.querySelector('#throttle').addEventListener('keyup', e => {
                    throttleAjax(e.target.value)
                })
            }
        </script>
    </body>
    </html>

    函数抖动

    原理 

    在事件被触发n秒后,再去执行回调函数。如果n秒内该事件被重新触发,则重新计时。结果就是将频繁触发的事件合并为一次,且在最后执行。

    例如  电梯5秒后会关门开始运作,如果有人进来,等待5秒,5秒之内又有人进来,5秒等待重新计时...直至超过5秒,电梯才开始运作

    使用场景

    input输入数据时请求服务器等。

    实现

    每当事件触发,就去重置定时器。直至最后一次事件被触发,n秒后再去执行回调函数

    <!DOCTYPE html>
    <html>
    <head>
        <title>加入防抖</title>
    </head>
    <body>
        <div>
            加入防抖:<input type="text" id="debounce"/>
        </div>
        <script>
            window.onload = () => {
                function ajax (data) {
                    console.log(new Date().toLocaleTimeString() + ' - ' + data)
                }
    
                function debounce (fn, delay) {
                    return args => {
                        clearTimeout(fn.id)
    
                        fn.id = setTimeout(() => {
                            fn.call(this, args)
                        }, delay)
                    }
                }
               
                const debounceAjax = debounce(ajax, 1000)
    
                document.querySelector('#debounce').addEventListener('keyup', e => {
                    debounceAjax(e.target.value)
                })
            }
        </script>
    </body>
    </html>

     参考链接:

    https://juejin.im/post/5caf39d8f265da03826106b8#heading-2

     

  • 相关阅读:
    PHP 包含文件路径问题
    PHP显示今天、今月、上月、今年的起点/终点时间戳
    PHP Web基础教程
    php如何生成随机密码的几种方法
    You don't have permission to access /~whpc on this server.
    linux 网络 PING IP可以通,ping域名ping不通
    CPU : 二级缓存容量
    简单建立个人WEB网站
    MKL程序编译与连接:Lapack篇
    ldd命令原理与使用
  • 原文地址:https://www.cnblogs.com/pikachuworld/p/13166882.html
Copyright © 2011-2022 走看看