唯品秀博客
首页 > 前端开发 > Javascript > 关于js函数节流与函数防抖【完美解决】

关于js函数节流与函数防抖【完美解决】

 2018年05月07日 作者: 管理员 1395次浏览

有些浏览器事件会被用户在很短的时间内触发很多次,例如点击事件或滚动页面。如果你给窗口滚动事件添加一个事件监听函数(事件句柄),然后用户不停地快速上下滚动页面,那你的事件可能在一秒之内都会被触发很多次,这会导致严重的性能问题,比如说你的页面卡住了(假死),所以我们需要降低触发回调的频率。

下面就说一下优化这种高频执行js的方法,来提高页面速度和性能。

预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新的时间周期。(设置阈值)

函数节流、防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
    <title>函数节流、防抖 - 打开控制台,滚动你的鼠标小滑轮试试看</title>
    <style>
        body {
            background: #fff
        }

        h1 {
            font-size: 24px;
            text-align: center;
            line-height: 36px;
            margin-top: 100px;
            font-weight: normal;
            font-family: "微软雅黑"
        }
    </style>
</head>

<body style="height:2000px;">
    <h1>函数节流、防抖</h1>
</body>
<script src="./jquery-2.1.4.min.js"></script>
<script>
    var isThrottle = true; //初始化无需走节流
    var setTimer = null; //初始化定时器
   
    var throttle = function (fn, time) {
        clearInterval(setTimer)
        var time = time || 300;
        if (isThrottle) { //注意:在这里第一次滚动时候我们是需要立马执行函数的,真正的节流是从第二次开始
            fn();
            isThrottle = false;
            return false;
            /*细节:这里如果你不return false阻断代码往下执行,那么在第一次时候实际还会走下面的else,也就是触发了两次,(因为滚轮触发的事件频率很高,第一次节流(else中)的事件会紧接着初始化第一次未节流事件去执行了)*/
        } else {
                        console.log('高频触发滚动事件中')
            setTimer = setTimeout(function () {
                fn();
                isThrottle = true;
                console.log('上一次打印是节流执行。。。')
            }, time)
        }
    }

    function conduct() {
        console.log("1")
    }
    $(document).scroll(function () {
        throttle(conduct, 1000);
    })
</script>

</html>

注意:当你第一次滚动时候,方法不会执行,这当然是属于Bug了,在第一次滚动时候我们应该第一时间执行这个方法,也就是说,真正节流应该是从第二次滚动时候才开始进行,也就是所谓的防抖,它的做法是限制下次函数调用之前必须等待的时间间隔,

在线一览

很显然,仅仅上面这样处理方式还是不够的,假设用户在mac触摸板下不停的滚动(我也是用mac才发现这个bug)这时候因为每次都会去触发节流函数,但是每次还没执行就被上一个清除定时器给清除了,所以在中途一直不会触发节流,只有每次用户停止才会去触发,很显然不可取,违背了我们的初衷

优化封装函数节流方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
    <title>函数节流、防抖 - 打开控制台,滚动你的鼠标小滑轮试试看</title>
    <style>
        body {
            background: #fff
        }

        h1 {
            font-size: 24px;
            text-align: center;
            line-height: 36px;
            margin-top: 100px;
            font-weight: normal;
            font-family: "微软雅黑"
        }
    </style>
</head>

<body style="height:2000px;">
    <h1>函数节流、防抖</h1>
</body>
<script src="./jquery-2.1.4.min.js"></script>
<script>
    function conduct(fn, delay, masExac) {
        var timer;
        var lastTime = new Date();
        return function (arg) {
            var now = new Date();
            clearTimeout(timer)
            if (now - lastTime < masExac) {
                timer = setTimeout(() => {
                    fn(arg);
                    lastTime = now;
                }, delay)
            } else {
                fn(arg);
                lastTime = now;
            }
        }
    }

    function Fn(data){
        console.log(data)
    }
    var throttle = conduct(Fn,1000,2000)
    $(document).scroll(function () {
        throttle('1')
    })
</script>

</html>

在线一览

最后解释下节流和防抖区别?节流就是在用户高频度操作时候,让事件不要高频触发,但在中途函数达到多久还没执行时候再去执行一次函数,这个时候用户还在操作过成功,也就是我们上文第二种方式。那么去抖则指的是在用户操作时候,首次触发一次,但在频繁操作过程中不会触发,只会在用户停下来后再去触发一次,也就是上文中的第一种方式。

「两年博客,如果觉得我的文章对您有用,请帮助本站成长」

赞( 2 ) 打赏

谢谢你请我吃鸡腿*^_^*

支付宝
微信
2

谢谢你请我吃鸡腿*^_^*

支付宝
微信
标签:

上一篇:

下一篇:

共有 0 条评论

博客简介

唯品秀博客: weipxiu.com,一个关注Web前端开发技术、关注用户体验、坚持更多原创实战教程的个人网站,愿景:成为宇宙中最具有代表性的前端博客,期待您的参与,了解更多...

精彩评论

风云英雄

他们同样是一群网虫,却不是每天泡在网上游走在淘宝和网游之间、刷着本来就快要透支的信用卡。他们或许没有踏出国门一步,但同学却不局限在一国一校,而是遍及全球!

站点统计

  • 文章总数: 164 篇
  • 草稿数目: 3 篇
  • 分类数目: 13 个
  • 页面总数: 21 个
  • 评论总数: 884 条
  • 链接总数: 10 个
  • 标签总数: 297 个
  • 建站时间: 800 天
  • 注册用户: 448 人
  • 访问总量: 8649654 次
  • 最近更新: 2019年2月19日
服务热线:
 182****8470

 QQ在线交流

 旺旺在线