javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > js防抖与节流

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

作者: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防抖与节流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文