No.40 JavaScript---防抖(debounce)、节流(throttle)

一、防抖

1.含义

  • 防抖严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。

2.从滚动条监听的例子说起

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h3{
            height: 500px;
        }
    </style>
</head>
<body>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <script>
        //滚动事件
        window.onscroll = scrollHandle;
        
        function scrollHandle(){
            var scrollTop = document.documentElement.scrollTop; //滚动条距顶部的高度

            console.log(scrollTop);
        }
    </script>
</body>
</html>

  

在运行的时候会发现存在一个问题:这个函数的默认执行频率,太!高!了!。高到什么程度呢?以chrome为例,我们可以点击选中一个页面的滚动条,然后点击一次键盘的【向下方向键】,会发现函数执行了8-9次!

 

  • 然而实际上我们并不需要如此高频的反馈,毕竟浏览器的性能是有限的,不应该浪费在这里,所以接着讨论如何优化这种场景。
  • 基于上述场景,首先提出第一种思路:在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后
    • ① 如果在200ms内没有再次触发滚动事件,那么就执行函数
    • ②如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时
    • 效果:如果短时间内大量触发同一事件,只会执行一次函数

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h3{
            height: 500px;
        }
    </style>
</head>
<body>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <script>
        //滚动事件
        function debounce(fn,delay){
            var timer = null;
            //闭包
            return function(){
                if(timer){
                    clearTimeout(timer)
                }
                timer = setTimeout(fn,delay)
            }
        }

        window.onscroll = debounce(scrollHandle,200);
        
        function scrollHandle(){
            var scrollTop = document.documentElement.scrollTop;

            console.log(scrollTop);
        }
    </script>
</body>
</html>

  

 

 到这里,已经把防抖实现了。

 

3.定义

  • 对于短时间内连续触发的事件(上面的滚动事件),防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次。

 

二、节流

  • 节流严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。(和防抖一样)
  • 上面防抖的效果有个小问题,就是用户按住滚动条拖动不放的时候,200ms也不会打印,直到放开滚动条才会打印。所以用节流来解决这个问题。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h3{
            height: 500px;
        }
    </style>
</head>
<body>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <h3>hah1</h3>
    <script>
        //滚动事件
        function throttle(fn,delay){
            var valid = true;
            return function(){
                if(!valid){
                    return false; 
                }
                valid = false;
                setTimeout(function(){
                    fn();
                    valid = true;
                },delay)
            }
        }

        window.onscroll = throttle(scrollHandle,2000);
        
        function scrollHandle(){
            var scrollTop = document.documentElement.scrollTop;

            console.log(scrollTop);
        }
    </script>
</body>
</html>

  

 

三、应用场景

百度是实时搜索

 

 

 

 

 

 

 

 

 

posted @ 2025-03-10 09:26  百里屠苏top  阅读(82)  评论(0)    收藏  举报