节流与防抖的讲解与其封装

本文讲解一下节流和防抖的原理,和简单的使用。然后做一下节流与防抖的封装。

目录

前言

节流与防抖的原理

节流:

解释:

防抖:

解释:

节流的封装

防抖的封装


扫描二维码关注公众号,回复: 14860298 查看本文章

前言

比如说我们写一个监听事件去监听鼠标在div里面的移动,或者监听滑块的移动,监听到变化就会触发函数。那么我们随便移动一下鼠标,拖动一下滑块,就会频繁触发函数去执行,执行几十甚至上百次。节流与防抖就是想办法,既能监听事件去执行函数,又可以避免频繁执行函数。

节流与防抖的原理

我们可以使用定时器来实现节流与防抖。

节流:

节流:就是减少函数的执行频率,一定时间内就执行一次。

比如说我写一个按钮,点击这个按钮就打印输出数字。每点击一下按钮,点击事件内的函数,函数内定义的变量num就要自增1,点击10次后,打印输出的就会是1.

而我不停的点击,在每隔一秒也会打印一次数字。

如下:

let btn = document.querySelector("button");
    let flag = true,
        number = 0;
    btn.onclick = function() {
        if (flag) {
            flag = false;
            number++;
            setTimeout(() => {
                flag = true;
                console.log(number);
            }, 1000);
        }
    }

解释:

我们在注册监听的函数里面,在监听到事件源发生改变的时候,其延时执行函数。使用定时器去延时执行函数。

我们使用"先关后开"的原理,先写一个开关,每次监听到事件源发生改变,就判断开关是否打开,如果打开就执行下一步,然后把开关关上,执行定时器,1s后定时器内函数开始执行,这时候在定时器内把开关打开。

再去触发事件源,因为开关被我们手动关上了,就不会再去执行下一步的东西,定时器也是不会再次执行,只有定时器执行的时候把开关打开,才能再去触发事件源再次执行定时器内的函数。

防抖:

防抖:在一定时间内,函数只执行最后一次。

比如说我写一个按钮,点击这个按钮就打印输出数字。每点击一下按钮,点击事件内的函数,函数内定义的变量num就要自增1,点击10次后,打印输出的就会是10.

而我不停的点击,只有在点击结束后才能打印出数字。

如下:

 var btn = document.querySelector("button");
    var number = 0;
    var timer;
    btn.onclick = function() {
        number++;
        clearTimeout(timer)
        timer = setTimeout(() => {
            show()
        }, 1000);
    }

    function show() {
        console.log(number);
    }

解释:

 我们在注册监听的函数里面,在监听到事件源发生改变的时候,其延时执行函数。使用定时器去延时执行函数。

我们使用"先清后开"的原理,每次监听到事件源发生改变,就先清空定时器,然后再去执行定时器,定时器在延时1s后执行内部代码打印数字。每次去触发事件源就会清空上一次触发事件源产生的定时器,"就是不断的去取消上一次的点击"。

所以,我们在频繁去触发事件源的时候,只有最后一次才是有用的。

节流的封装

其实封装了两个,一个点击事件+节流的函数。先设置事件监听(addEventListener)的封装,在给触发事件源后的函数设置了节流的封装。

let btn = document.querySelector('button')//获取button
        //把函数赋值给fun,这是节流后要执行的函数
        let fun = function () { console.log('标准浏览器') }
        //controls是元素,events是事件,buer是布尔值决定是否支持冒泡
        function Throttling(controls, events, buer) {//节流的封装与传参
            //事件添加的封装,fn是节流函数
            controls.addEventListener(events, fn(fun), buer)
        }
        function fn(fun) {//节流函数,传的参是防抖后需要执行的函数
            let timer = null//先定义timer
            let time = true//定义开关time,先设置为开
            return function () {
                //如果time是true,就执行下面的代码
                if (time) {
                    time = false//把time设置为false
                    timer = setTimeout(//定时器启动
                        function () {
                            time = true//打开开关
                            fun()//节流后执行的函数
                        }, 1000)
                }
            }
        }
        Throttling(btn, 'click', false)

防抖的封装

其实封装了两个,一个点击事件+防抖的函数。先设置事件监听(addEventListener)的封装,在给触发事件源后的函数设置了防抖的封装。

let btn = document.querySelector('button')//获取button
         //把函数赋值给fun,这是节流后要执行的函数
        let fun = function () { console.log('标准浏览器') }
        //controls是元素,events是事件,buer是布尔值决定是否支持冒泡
        function Throttling(controls, events, buer) {//节流的封装与传参
            //事件添加的封装,fn是节流函数
            controls.addEventListener(events, fn(fun), buer)
        }
        function fn(fun) {//节流函数,传的参是防抖后需要执行的函数
            let timer = null//先定义timer
            let time = true//定义开关time,先设置为开
            return function () {
                //如果timer不是false,那就先清空定时器
                if (time !== false) {
                    clearTimeout(timer)
                }
                timer = setTimeout(//定时器启动
                    function () {
                        fun()//节流后执行的函数
                    }, 500)
                time = true//打开开关
            }
        }
        Throttling(btn, 'click', false)

写的不好,也请大家多多批评。

猜你喜欢

转载自blog.csdn.net/zhangawei123/article/details/127873197