美文网首页
函数防抖和节流

函数防抖和节流

作者: Rudy_Ran | 来源:发表于2019-08-06 15:54 被阅读0次

    定义

    在JS里,有一些事件是很容易频繁触发的,比如窗口的resizescroll、鼠标的onmousemove等操作,在事件频繁触发的过程中,不可避免的导致频繁执行触发事件中的函数。为了防止这种情况的发生,主流的解决方案有两种,防抖debounce)和节流(throttle)

    频繁执行情况

                var num = 1;
                var moveCntent = document.getElementById('example')
                function count(){
                    moveCntent.innerHTML++;
                }
                moveCntent.onmousemove = count
    

    效果如下:



    可以明显的看到,count 函数执行的非常频繁,假如现在我们count函数里执行的是一个Ajax请求,那么问题就会非常严重了。

    防抖

    函数防抖就是在一段时间(n毫秒)触发或调用函数时,只执行一次; 也可以理解为触发n毫秒之后才会调用一次。

    防抖函数的写法主要有两种,非立即执行版本立即执行版本

    非立即执行版

                    var num = 1;
                    var moveCntent = document.getElementById('example')
                    function count(){
                            moveCntent.innerHTML++;
                    }
                    moveCntent .onmousemove = count
                    function debounce(fn,delay){
                            var timer;
                            return function(){
                                var _this = this;
                                var args = arguments;
                                if(timer) clearTimeout(timeout);
                                timer = setTimeout(function(){
                                    fn.apply(_this,args)
                                },delay)
                                }
                        }
                    moveCntent.onmousemove = debounce(count,1000)
    

    原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

    效果如下:



    在触发事件1秒后才执行,如果在触发事件的一秒内又触发了事件,则重新计算函数执行时间

    立即执行版

                    function debounce(fn,delay){
                        var timer;
                        return function(){
                            var _this = this;
                            var args = arguments;
                            if(timer){
                                clearTimeout(timer);
                            } 
                            if(!timer){
                                fn.apply(_this,args);
                            } 
                            timer = setTimeout(function(){
                                timer = null;
                            },delay);
                        };
                    }
    

    立即执行版本和非例行版本的区别是:

    • 立即执行版本:触发事件后函数立即执行,然后n秒内不触发时间才会继续执行
    • 非立即执行版本:触发事件后函数不会立即执行,而是在n秒回才会执行

    节流

    函数节流,就是指连续触发的事件在n秒钟只执行一次函数。降低函数的执行频率,对于函数节流,通常也也有两种方式实现,分别是时间戳版定时器版

    时间戳版

                    function throttle(fn,delay){
                        var previous = 0;
                        return function(){
                            var now = Date.now();
                            var _this = this;
                            var args = arguments;
                            if(now - previous > delay){
                                fn.apply(_this,args);
                                previous = now;
                            }
                        };
                    }
                    moveCntent.onmousemove = throttle(count,1000)
    

    当高频事件触发时,第一次会立即执行,而后再怎么频繁地触发事件,也都是每delay时间才执行一次。

    效果如下:



    持续触发事件的过程中,函数会立即执行,并且每一秒执行一次

    定时器版

                    function throttle(fn,delay){
                        var timer;
                        return function(){
                            var _this = this;
                            var args = arguments;
                            if(!timer){
                                timer = setTimeout(function(){
                                    timer = null;
                                    fn.apply(_this,args);
                                },delay);
                            }
                        };
                    }
    

    在持续触发事件的过程中,函数不会立即执行,并且每一秒执行一次,停止触发事件后,还会再执行一次

    效果如下:



    时间戳版本和定时器版本的区别是:

    • 时间戳版本:触发事件后函数立即执行,每n秒执行一次
    • 定时器版本:触发事件后函数不会立即执行,每n秒执行一次,停止触发后还会执行一次

    总结

    函数防抖:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

    函数节流:使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。

    区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。

    相关文章

      网友评论

          本文标题:函数防抖和节流

          本文链接:https://www.haomeiwen.com/subject/wehwdctx.html