前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >防抖和节流 原

防抖和节流 原

作者头像
tianyawhl
发布2019-04-04 09:59:28
6680
发布2019-04-04 09:59:28
举报
文章被收录于专栏:前端之攻略前端之攻略

浏览器的一些事件,如:resize,scroll,keydown,keyup,keypress,mousemove等。这些事件触发频率太过频繁,绑定在这些事件上的回调函数会不停的被调用。会加重浏览器的负担,导致用户体验非常糟糕,不知哪个大神发明了防抖和节流,用来控制回调函数的次数。

代码语言:javascript
复制
    //函数防抖(debounce)
    function debounce(fn, wait) {
        var timeout;
         return function() {
            if (timeout) {
                clearTimeout(timeout);
            }
            timeout = setTimeout(fn, wait);
        }
    }

    function handle() {
        console.log(12)
    }
    //滚动事件
    window.addEventListener("scroll", debounce(handle, 1000))

代码解释:先执行debounce(handle, 1000)返回一个匿名函数,然后监听scroll事件,执行匿名函数,设置一个1秒后执行handle函数的定时器,由于scroll是不断触发的,如果第一次触发与第二次触发间隔1秒或者1秒多,第一次触发scroll会执行handle函数,在控制台上会打印12,如果间隔小于1秒,因为setTimeout(fn, wait)是要在1秒后执行handle 函数,小于1秒就不执行handle函数,但是timeout定时器已经不为空,第二次scroll滚动触发debounce时就执行clearTimeout(timeout),并且执行下面的代码,因为下面的代码不是放在else里面,依次类推。 总结:如果不停的触发事件,事件间隔大于设定的时间,才执行某个函数。

如果是input的情况,这时需要传递数据

代码语言:javascript
复制
  //函数节流(throttle)
    var throttle = function(func, delay) {
        console.log("hi")
        var prev = Date.now(); //返回1970 年 1 月 1日午夜与当前日期和时间之间的毫秒数。
        return function() {
            var now = Date.now();
            if (now - prev >= delay) {
                func()
                prev = Date.now()
            }
        }
    }

    function handle() {
        console.log(Math.random())
    }

    window.addEventListener("scroll", throttle(handle, 1000))

解释:当持续触发事件时,每隔一定时间(如200ms)执行一次事件处理函数 先执行throttle(handle, 1000)返回一个匿名函数,然后触发scroll事件时执行返回的匿名函数,即未滚动的时候已经执行了throttle(handle, 1000)函数

如果是input的情况(防抖)

代码语言:javascript
复制
<body>
    <div style="" class="">
        <input type="" id="unDebounce" />
    </div>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script>
    <script type="text/javascript">
    function ajax(content) {
        console.log("ajax request" + content)
    }

    function debounce(fun, delay) {
        var timeout;
        return function(args) {
            if (timeout) {
                clearTimeout(timeout)
            }
            timeout = setTimeout(function() {
                fun(args)
            }, delay)
          
        }
    }
    let inputElement = document.getElementById("unDebounce")
    let debounceAjax = debounce(ajax, 500)
    inputElement.addEventListener("keyup", function() {
        //debounceAjax(this.value)放在匿名函数里面的原因是当keyup的时候才执行,如果不放在里面会先执行此函数,导致没有值
        debounceAjax(this.value)
    })
	</script>
</body>

如果是input的情况(节流)  

代码语言:javascript
复制
<body>
    <div style="" class="">
        <input type="" id="throttle" />
    </div>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script>
    <script type="text/javascript">
    function ajax(content) {
        console.log("ajax request" + content)
    }

    function throttle(func, delay) {
        var pre = Date.now();
        var deferTimer;
        console.log("pre " + pre)
        return function(args) {
            var now = Date.now()
            console.log("now " + now)
            console.log(now - pre)
            if (now - pre >= delay) {
                func(args)
                pre = Date.now()
            } else {
                clearTimeout(deferTimer);
                deferTimer = setTimeout(function() {
                    func(args)
                    pre = Date.now()
                }, delay)

            }
        }
    }

    var throttleAjax = throttle(ajax, 2000)

    var inputc = document.getElementById('throttle')
    inputc.addEventListener('keyup', function() {
        throttleAjax(this.value)
    })
    </script>
</body>

防抖和节流的区别: 防抖是根据事件间隔是否大于设定的值来决定回调函数是否执行(取决于事件间隔,或者最后一次滚动); 节流是根据事件不停触发时时间间隔大于设定的值才执行回调函数(每隔多少秒执行一次);

公众号:前端之攻略

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018/10/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档