通过代码实验演示js的防抖与节流(超详细解释)

 更新时间:2026年03月16日 09:40:52   作者:Insecure Fluoxetine  
在前端开发中经常会遇到一些高频触发的事件,比如scroll、resize、input等,如果对这些事件的处理函数不加以限制,可能会导致性能问题,防抖和节流是优化高频事件的得力工具,这篇文章主要介绍了如何通过代码实验演示js的防抖与节流的相关资料,需要的朋友可以参考下

1.字面解释--防抖与节流

1. 防抖(Debounce)定义 :在事件触发后等待指定时间再执行,如果在等待时间内再次触发,则重新计时。原理 :在于使用定时器,每次事件触发时清除之前的定时器,重新设置新的定时器。 应用场景 :搜索框输入联想、窗口大小调整事件、表单验证、按钮频繁点击。

2. 节流(Throttle)定义 :在指定时间内只执行一次,无论事件触发多少次。原理 :使用标志位控制,在指定时间内只允许执行一次函数。应用场景 :滚动事件、鼠标移动事件、按钮快速点击、动画效果。

2.二者有什么不同呢?

关键不同点:防抖 :连续触发时,只在最后一次触发后执行一次。节流 :连续触发时,在指定时间间隔内定期执行。

3.代码演示准备 --(可先看实验结果之后再看实验代码)

我们以设置test1为实验对象

先写入test1.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript 防抖与节流示例</title>
    <link rel="stylesheet" href="css/test1.css" rel="external nofollow" >
</head>
<body>
    <div class="container">
        <h1>JavaScript 防抖与节流</h1>
        
        <div class="section">
            <h2>1. 防抖 (Debounce)</h2>
            <p>防抖:在事件触发后等待指定时间再执行,如果在等待时间内再次触发,则重新计时。</p>
            <p>适用场景:搜索框输入、窗口大小调整、表单验证等。</p>
            
            <div class="demo">
                <label for="debounce-input">搜索输入:</label>
                <input type="text" id="debounce-input" placeholder="输入内容...">
                <div id="debounce-result">搜索结果将显示在这里...</div>
            </div>
        </div>
        
        <div class="section">
            <h2>2. 节流 (Throttle)</h2>
            <p>节流:在指定时间内只执行一次,无论事件触发多少次。</p>
            <p>适用场景:滚动事件、鼠标移动、按钮点击等。</p>
            
            <div class="demo">
                <button id="throttle-button">快速点击我</button>
                <div id="throttle-result">点击次数:0</div>
            </div>
        </div>
        
        <div class="section">
            <h2>3. 对比演示</h2>
            <p>同时展示防抖和节流的效果对比:</p>
            
            <div class="comparison">
                <div class="demo">
                    <h3>防抖效果</h3>
                    <input type="text" id="compare-debounce" placeholder="输入内容...">
                    <div id="compare-debounce-result">结果:</div>
                </div>
                
                <div class="demo">
                    <h3>节流效果</h3>
                    <input type="text" id="compare-throttle" placeholder="输入内容...">
                    <div id="compare-throttle-result">结果:</div>
                </div>
            </div>
        </div>
    </div>
    
    <script src="js/test1.js"></script>
</body>
</html>

test1.css代码--渲染结果

/* 全局样式 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    line-height: 1.6;
    color: #333;
    background-color: #f5f5f5;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

/* 标题样式 */
h1 {
    text-align: center;
    margin-bottom: 40px;
    color: #2c3e50;
    font-size: 2.5rem;
}

h2 {
    color: #3498db;
    margin-bottom: 20px;
    font-size: 1.8rem;
    border-bottom: 2px solid #3498db;
    padding-bottom: 10px;
}

h3 {
    color: #2ecc71;
    margin-bottom: 15px;
    font-size: 1.4rem;
}

/* 段落样式 */
p {
    margin-bottom: 15px;
    font-size: 1.1rem;
    color: #555;
}

/* 区块样式 */
.section {
    background-color: #fff;
    padding: 30px;
    margin-bottom: 30px;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

/* 演示区域样式 */
.demo {
    background-color: #f8f9fa;
    padding: 20px;
    border-radius: 8px;
    border-left: 4px solid #3498db;
    margin-top: 20px;
}

label {
    display: block;
    margin-bottom: 10px;
    font-weight: bold;
    color: #2c3e50;
}

input[type="text"] {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 1rem;
    margin-bottom: 15px;
}

button {
    background-color: #3498db;
    color: #fff;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    font-size: 1rem;
    cursor: pointer;
    transition: background-color 0.3s;
}

button:hover {
    background-color: #2980b9;
}

/* 结果显示样式 */
#debounce-result, #throttle-result, #compare-debounce-result, #compare-throttle-result {
    margin-top: 15px;
    padding: 15px;
    background-color: #e3f2fd;
    border-radius: 4px;
    min-height: 50px;
    font-size: 1rem;
    color: #1565c0;
}

/* 对比区域样式 */
.comparison {
    display: flex;
    gap: 20px;
    margin-top: 20px;
}

.comparison .demo {
    flex: 1;
}

/* 响应式设计 */
@media (max-width: 768px) {
    .comparison {
        flex-direction: column;
    }
    
    h1 {
        font-size: 2rem;
    }
    
    h2 {
        font-size: 1.5rem;
    }
    
    h3 {
        font-size: 1.2rem;
    }
}

js代码如下:

// 防抖函数实现
function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        // 清除之前的定时器
        clearTimeout(timeoutId);
        // 设置新的定时器
        timeoutId = setTimeout(() => {
            func.apply(this, args);
        }, delay);
    };
}

// 节流函数实现
function throttle(func, limit) {
    let inThrottle;
    return function(...args) {
        if (!inThrottle) {
            // 执行函数
            func.apply(this, args);
            // 设置节流状态
            inThrottle = true;
            // 一段时间后恢复
            setTimeout(() => {
                inThrottle = false;
            }, limit);
        }
    };
}

// 防抖演示:搜索框输入
const debounceInput = document.getElementById('debounce-input');
const debounceResult = document.getElementById('debounce-result');

// 模拟搜索函数
function simulateSearch(query) {
    debounceResult.innerHTML = `正在搜索 "${query}"...`;
    
    // 模拟异步搜索
    setTimeout(() => {
        if (query.trim() === '') {
            debounceResult.innerHTML = '请输入搜索内容...';
        } else {
            debounceResult.innerHTML = `搜索结果:找到 ${Math.floor(Math.random() * 100)} 条关于 "${query}" 的结果`;
        }
    }, 500);
}

// 使用防抖包装搜索函数
const debouncedSearch = debounce(simulateSearch, 300);

// 绑定输入事件
debounceInput.addEventListener('input', (e) => {
    debouncedSearch(e.target.value);
});

// 节流演示:按钮点击
const throttleButton = document.getElementById('throttle-button');
const throttleResult = document.getElementById('throttle-result');
let clickCount = 0;

// 点击处理函数
function handleClick() {
    clickCount++;
    throttleResult.innerHTML = `点击次数:${clickCount}`;
}

// 使用节流包装点击处理函数
const throttledClick = throttle(handleClick, 1000);

// 绑定点击事件
throttleButton.addEventListener('click', throttledClick);

// 对比演示
const compareDebounceInput = document.getElementById('compare-debounce');
const compareDebounceResult = document.getElementById('compare-debounce-result');
const compareThrottleInput = document.getElementById('compare-throttle');
const compareThrottleResult = document.getElementById('compare-throttle-result');

// 防抖对比
function updateDebounceResult(query) {
    compareDebounceResult.innerHTML = `结果:${query}`;
}

const debouncedUpdate = debounce(updateDebounceResult, 500);

compareDebounceInput.addEventListener('input', (e) => {
    compareDebounceResult.innerHTML = '等待输入完成...';
    debouncedUpdate(e.target.value);
});

// 节流对比
function updateThrottleResult(query) {
    compareThrottleResult.innerHTML = `结果:${query}`;
}

const throttledUpdate = throttle(updateThrottleResult, 500);

compareThrottleInput.addEventListener('input', (e) => {
    compareThrottleResult.innerHTML = '处理中...';
    throttledUpdate(e.target.value);
});

// 页面加载完成后显示说明
window.addEventListener('load', () => {
    console.log('防抖与节流演示页面加载完成!');
    console.log('防抖:在事件触发后等待指定时间再执行,如果在等待时间内再次触发,则重新计时。');
    console.log('节流:在指定时间内只执行一次,无论事件触发多少次。');
});

4.我的结果演示:

初始页:

1.防抖演示

当我在二者都启用时,先从防抖开始,根据防抖一般应用于反复搜索、注册等场景,这里是使用了反复搜索的场景。当我随意搜索一些内容时,只有停止输入一段时间后(显示正在搜索“”)后才执行搜索(模拟真实搜索场景),避免频繁请求,你想假如没有这个的话,你反复输入或回车搜索,它就会不断发送搜索请求,造成大量卡顿,而防抖就是为了防止这样场景发生。用户输入时,通过防抖减少API请求次数(避免输入过程中每次按键都请求)。

2.节流演示

根据节流一般应用于滚动事件、鼠标移动事件、按钮快速点击、动画效果的场景。这里实验用的是按钮快速点击事件,当我快速点击按钮时,“节流”会限制每秒最多执行一次点击事件,避免重复处理。主要就是按钮防重复点击 :通过节流限制点击频率(避免用户快速点击导致重复提交)。正常我们设置点击按钮,根据点击来计算点击次数,这个是存粹计算点击次数,但我们在实际应用的时候,你反复点击一个按钮可能会导致导致重复提交,造成资源损耗卡顿,而这是通过时间来限制点击次数,1s内点击一次才有效,1s内点击多次都不计数无效,无效。

5.对比总结

防抖(Debounce)和节流(Throttle)是前端开发中抽象的性能优化概念,test1通过 直观的交互演示 将其具体化:

- 防抖演示 :搜索框输入时,只有停止输入一段时间后才执行搜索(模拟真实搜索场景),避免频繁请求。

- 节流演示 :快速点击按钮时,限制每秒最多执行一次点击事件,避免重复处理。

实验的核心意义在于 建立前端性能优化的思维 :

- 高频事件( input 、 click 、 scroll 、 resize )会触发大量函数调用,导致页面卡顿。

- 防抖/节流通过 限制函数执行频率 ,减少不必要的计算和DOM操作,提升页面流畅度。

- 实验通过控制台输出和结果显示,让开发者直观感受优化前后的性能差异。

到此这篇关于通过代码实验演示js防抖与节流的文章就介绍到这了,更多相关js防抖与节流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js自定义事件及事件交互原理概述(二)

    js自定义事件及事件交互原理概述(二)

    上一篇的目的只是让大家简单的理解自定事件是如何模拟出来的,大家不难发现会有很多缺陷,本篇主要已解决上一篇的问题为主,感兴趣的朋友可以参考,或许本文对你有所帮助
    2013-02-02
  • JavaScript TWaver使用中间点画折线的方法

    JavaScript TWaver使用中间点画折线的方法

    这篇文章主要介绍了JavaScript TWaver使用中间点画折线的方法,TWaver的图形组件库中提供了拓扑组件、地图组件、设备图组件,以及表格、树图、属性表、图表等丰富的通用图形界面组件
    2022-07-07
  • JS setCapture 区域外事件捕捉

    JS setCapture 区域外事件捕捉

    鼠标捕获(setCapture)作用是将鼠标事件捕获到当前文档的指定的对象。这个对象会为当前应用程序或整个系统接收所有鼠标事件。
    2010-03-03
  • 小程序实现背景音乐播放和暂停

    小程序实现背景音乐播放和暂停

    这篇文章主要为大家详细介绍了小程序实现背景音乐播放和暂停,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • JS+CSS实现实用的单击输入框弹出选择框的方法

    JS+CSS实现实用的单击输入框弹出选择框的方法

    这篇文章主要介绍了JS+CSS实现实用的单击输入框弹出选择框的方法,实例分析了javascript操作select及button的操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • NodeJS 模块开发及发布详解分享

    NodeJS 模块开发及发布详解分享

    NodeJS 是一门年轻的语言,扩展模块并不太全,经常我们想用某个模块但是却找不到合适的
    2012-03-03
  • 深入理解JS实现快速排序和去重

    深入理解JS实现快速排序和去重

    在js面试中快速排序和数组去重是比较常问的面试题,下面小编给大家分享下我对JS实现快速排序和去重的理解,感兴趣的朋友一起看看吧
    2016-10-10
  • JS实现简易留言板增删功能

    JS实现简易留言板增删功能

    这篇文章主要为大家详细介绍了JS实现简易留言板增删功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • JavaScript动态代理的各种用法详解

    JavaScript动态代理的各种用法详解

    动态代理是ES6引入的强大功能,通过Proxy对象实现,允许你拦截和自定义对目标对象的操作,下面我将全面介绍JavaScript动态代理的各种用法,需要的朋友可以参考下
    2025-09-09
  • 一起来学习JavaScript的BOM操作

    一起来学习JavaScript的BOM操作

    这篇文章主要为大家详细介绍了JavaScript BOM操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03

最新评论