JS节流和防抖

目录

1. JS节流和防抖的应用场合

2. 未使用节流和防抖的情况

3. js防抖

4. js节流
1. JS节流和防抖的应用场合

在网页实际运行的某些场景下,有些事件时会被不间断的被触发的,如resize事件,而不像是我们想象中的,滚动一次触发一次。这种情况下,由于过于频繁地DOM操作和资源加载,严重影响了网页性能,甚至会造成浏览器崩溃。

常见应用场景:

(1)window的 resize 和 scroll 事件;

        如:滚动到页面底部加载更多,稍微滚动一下就会触发n多次scroll事件,如果每次触发scroll事件的时候都去判断一次是否已经滚动到了页面底部,无疑会造成资源的浪费。此时若使用js节流,每隔一定的时间(如500ms)进行一次判断,间隔期间只能有一次触发判断,既节省了资源,也不会影响用户体验。

(2)文字输入时的 keyup 事件;

        如:输入搜索关键词的时候,进行自动完成或者自动联想。同理,这种情况下用户每敲击一次键盘就会触发一次keyup事件,此时用户可能连一个字都没有输入完成==,此时可以使用js防抖,在用户停止输入的一段时间后(如500ms)触发判断,进行自动联想或者自动搜索;也可以使用js节流,每隔一段时间,进行一次判断的执行,既可以实现实时的自动联想,也不会出现过于频繁的请求。

(3)元素拖拽、移动时的 mousemove 事件;

(4)……
2. 未使用节流和防抖的情况

以输入框的keyup事件为例,若未使用函数防抖,则:

        <div class="container">
            <label for="unDebounce">没有防抖的input</label>
            <input type="text" id="unDebounce" />
            <br>
            <br>
            <label for="debounce">防抖后的input</label>
            <input type="text" id="debounce" />
            <br>
            <br>
            <label for="throttle">节流后的input</label>
            <input type="text" id="throttle" />
        </div>

        $(function () {
            function time() {
                let date = new Date();
                let h = date.getHours();
                let m = date.getMinutes();
                let s = date.getSeconds();
                h = h >= 10 ? h : '0' + h;
                m = m >= 10 ? m : '0' + m;
                s = s >= 10 ? s : '0' + s;
                return h + ':' + m + ':' + s;
            }
            // 模拟ajax请求
            function ajax(value, time) {
                console.log('ajax: ' + value + ';   time: ' + time);
            }
            // 未防抖的输入框keyup事件
            $("#unDebounce").on('keyup', function (e) {
                ajax(e.target.value, time());
            })
        })

执行的结果如下:

可以看到,每秒都会执行多次console事件。
3. js防抖

    在事件被触发的n秒后执行回调,如果在这n秒内又被触发,则重新计时。

        // 防抖后的input的keyup事件
        function debounce(callback, delay) {
            let timerId = null;
            return function (args) {
                let that = this;
                clearTimeout(timerId);
                timerId = setTimeout(function () {
                    callback.call(that, args, time());
                }, delay);
            }
        }
        let debounceAjax = debounce(ajax, 500);
        $("#debounce").on('keyup', function (e) {
            debounceAjax(e.target.value);
        })

执行结果如下:

可以看到,如果用户不断输入,则不会触发console事件,这是由于在规定的 500ms 时间间隔内重新触发了keyup事件,定时器重新开始计时。当用户在500ms的间隔内没有进行输入,则会触发事件。适用于实时判断用户输入的内容(如邮箱、电话)是否符合格式要求等场景。
4. js节流

    规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

        function throttle(callback, delay) {
            let last, deferId;
            return function (args) {
                let that = this;
                // let now = new Date().getTime();
                let now = +new Date();
                if (last && now < last + delay) {
                    clearTimeout(deferId);
                    deferId = setTimeout(function () {
                        last = now;
                        callback.call(that, args, time());
                    }, delay);
                } else {
                    last = now;
                    callback.call(that, args, time());
                }
            }
        }
     
        let throttleAjax = throttle(ajax, 1000);
        $("#throttle").on('keyup', function (e) {
            throttleAjax(e.target.value);
        })

执行结果如下:

可以看到,及时用户不间断的输入内容,事件也只会按照预设的时间间隔(1000ms)进行触发 。js节流比较适用于滚动到页面底部自动加载更多、射击小游戏的射击事件(无论点击多么频繁,子弹射击的最短间隔都是一定的)等场景。

PS:这么写貌似还有点小问题,就是停顿一下,再继续输入,有时候会出现同一秒调用了两次?继续研究中……
---------------------
作者:Jennifer_xmj
来源:CSDN
原文:https://blog.csdn.net/xiaomajia029/article/details/82657319
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值