函数防抖与节流

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, 1000,500);
    //第一次事件触发,则先执行debounce函数,在执行闭包函数,一步一步执行,第一次以后的每次事件触发都是直接执行debounce函数中的闭包函数
</script>

原文地址:https://www.cnblogs.com/SRH151219/p/10368959.html

时间: 2024-11-07 15:28:37

函数防抖与节流的相关文章

前端进击的巨人(八):浅谈函数防抖与节流

本篇课题,或许早已是烂大街的解读文章.不过春招系列面试下来,不少伙伴们还是似懂非懂地栽倒在(-面试官-)深意的笑容之下,权当温故知新. JavaScript的执行过程,是基于栈来进行的.复杂的程序代码被封装到函数中,程序执行时,函数不断被推入执行栈中.所以 "执行栈" 也称 "函数执行栈". 函数中封装的代码块,一般都有相对复杂的逻辑处理(计算/判断),例如函数中可能会涉及到 DOM 的渲染更新,复杂的计算与验证, Ajax 数据请求等等. 前端页面的操作权,大部分

vue函数防抖和节流

Vue函数防抖和节流https://zhuanlan.zhihu.com/p/72363385 <template> <div> <input type='text' v-model='value' @keydown = "hangleChange"> </div> </template> <script> function debounce(func, wait=1000){ let timeout; retur

函数防抖与节流[转载]

underscore.js提供了很多很有用的函数,两个函数都用于限制函数的执行. debounce 在解释这个函数前,我们先从一个例子看下这个函数的使用场景.假设我们网站有个搜索框,用户输入文本我们会自动联想匹配出一些结果供用户选择.我们可能首先想到的做法就是监听keypress事件,然后异步去查询结果.这个方法本身是没错的,但是如果用户快速的输入了一连串的字符,假设是10个字符,那么就会在瞬间触发了10次的请求,这无疑不是我们想要的.我们想要的是用户停止输入的时候才去触发查询的请求,这时候函数

javaScript基本功之函数防抖与节流

1.函数节流与防抖 函数的节流与防抖是一种优化频繁调用时优化的方案. 比如canvas画笔时频繁获取位置点绘画会增大客服端CPU压力,那么就需要那控制频繁操作为一个范围内来优化而不影响绘画效果, 这样能让页面浏览更加顺畅,不会因为js的执行而发生卡顿. 函数节流是指一定时间内js方法只调用一次.比如人的眨眼睛,就是一定时间内眨一次.这是函数节流最形象的解释.函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次.比如生活中的坐公交,就是一定时间内,如果有人陆续刷卡上车,司机就不会开车.

函数防抖和节流*(性能优化不错的选择)

函数节流: 频繁触发,但只在特定的时间内才执行一次代码 函数防抖: 频繁触发,但只在特定的时间内没有触发执行条件才执行一次代码(如果一个事件被频繁触发多次,节流函数可以按照固定频率去执行对应的事件处理方法) 两者区别在于函数节流是固定时间做某一件事,比如每隔1秒发一次请求.而函数防抖是在频繁触发后,只执行一次(两者的前提都是频繁触发) 函数节流的应用场景一般是onrize,onscroll等这些频繁触发的函数,比如你想获取滚动条的位置,然后执行下一步动作,如果监听后执行的是Dom操作,这样的频繁

函数防抖和节流的结合

函数节流有个毛病,就是最后一次事件执行后,如果距离上一次事件执行不到规定时间,那么最后一次事件就不会执行,解决方法就是把事件函数节流和防抖结合在一起 function throlle(callback,delay){ let startTime=0; let timer=null; return function (){ //使用new Date().getTime(),这样首次操作一定会执行 let endTime=new Date().getTime(); clearTimeout(time

函数防抖和节流

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

2019 面试准备 - JS 防抖与节流 (超级 重要!!!!!)

Hello 小伙伴们,如果觉得本文还不错,记得给个 star , 你们的 star 是我学习的动力!GitHub 地址 本文涉及知识点: 防抖与节流 重绘与回流 浏览器解析 URL DNS 域名解析 TCP 三次握手与四次挥手 浏览器渲染页面 在本文中,jsliang 会讲解通过自我探索后关于上述知识点的个人理解,如有纰漏.疏忽或者误解,欢迎各位小伙伴留言指出. 如果小伙伴对文章存有疑问,想快速得到回复. 或者小伙伴对 jsliang 个人的前端文档库感兴趣,也想将自己的前端知识整理出来. 欢迎

JS 函数防抖和函数节流

我们都知道频繁触发执行一段js逻辑代码对性能会有很大的影响,尤其是在做一些效果实现方面,或者逻辑中需要进行后端请求,更是会导致卡顿,效果失效等结果,所以在处理类似的情况时,可以考虑使用函数节流和函数去抖来解决,至于具体使用哪一种方式,根据实际情况分析定夺,先来讲解一些这两者的概念 函数节流:在频繁触发的情况下,需要执行的逻辑只有执行完之后,才能继续执行下一次 函数防抖:在频繁触发的情况下,只有足够的空闲时间,才执行代码一次,如果没有执行完就清除掉,重新执行逻辑 应用场景:高频触发以下方法 页面滚