通過代碼實驗演示js的防抖與節(jié)流(超詳細解釋)
1.字面解釋--防抖與節(jié)流
1. 防抖(Debounce)定義 :在事件觸發(fā)后等待指定時間再執(zhí)行,如果在等待時間內再次觸發(fā),則重新計時。原理 :在于使用定時器,每次事件觸發(fā)時清除之前的定時器,重新設置新的定時器。 應用場景 :搜索框輸入聯(lián)想、窗口大小調整事件、表單驗證、按鈕頻繁點擊。
2. 節(jié)流(Throttle)定義 :在指定時間內只執(zhí)行一次,無論事件觸發(fā)多少次。原理 :使用標志位控制,在指定時間內只允許執(zhí)行一次函數(shù)。應用場景 :滾動事件、鼠標移動事件、按鈕快速點擊、動畫效果。
2.二者有什么不同呢?
關鍵不同點:防抖 :連續(xù)觸發(fā)時,只在最后一次觸發(fā)后執(zhí)行一次。節(jié)流 :連續(xù)觸發(fā)時,在指定時間間隔內定期執(zhí)行。
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 防抖與節(jié)流示例</title>
<link rel="stylesheet" href="css/test1.css" rel="external nofollow" >
</head>
<body>
<div class="container">
<h1>JavaScript 防抖與節(jié)流</h1>
<div class="section">
<h2>1. 防抖 (Debounce)</h2>
<p>防抖:在事件觸發(fā)后等待指定時間再執(zhí)行,如果在等待時間內再次觸發(fā),則重新計時。</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. 節(jié)流 (Throttle)</h2>
<p>節(jié)流:在指定時間內只執(zhí)行一次,無論事件觸發(fā)多少次。</p>
<p>適用場景:滾動事件、鼠標移動、按鈕點擊等。</p>
<div class="demo">
<button id="throttle-button">快速點擊我</button>
<div id="throttle-result">點擊次數(shù):0</div>
</div>
</div>
<div class="section">
<h2>3. 對比演示</h2>
<p>同時展示防抖和節(jié)流的效果對比:</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>節(jié)流效果</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;
}
/* 區(qū)塊樣式 */
.section {
background-color: #fff;
padding: 30px;
margin-bottom: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* 演示區(qū)域樣式 */
.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;
}
/* 對比區(qū)域樣式 */
.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代碼如下:
// 防抖函數(shù)實現(xiàn)
function debounce(func, delay) {
let timeoutId;
return function(...args) {
// 清除之前的定時器
clearTimeout(timeoutId);
// 設置新的定時器
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// 節(jié)流函數(shù)實現(xiàn)
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
// 執(zhí)行函數(shù)
func.apply(this, args);
// 設置節(jié)流狀態(tài)
inThrottle = true;
// 一段時間后恢復
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
// 防抖演示:搜索框輸入
const debounceInput = document.getElementById('debounce-input');
const debounceResult = document.getElementById('debounce-result');
// 模擬搜索函數(shù)
function simulateSearch(query) {
debounceResult.innerHTML = `正在搜索 "${query}"...`;
// 模擬異步搜索
setTimeout(() => {
if (query.trim() === '') {
debounceResult.innerHTML = '請輸入搜索內容...';
} else {
debounceResult.innerHTML = `搜索結果:找到 ${Math.floor(Math.random() * 100)} 條關于 "${query}" 的結果`;
}
}, 500);
}
// 使用防抖包裝搜索函數(shù)
const debouncedSearch = debounce(simulateSearch, 300);
// 綁定輸入事件
debounceInput.addEventListener('input', (e) => {
debouncedSearch(e.target.value);
});
// 節(jié)流演示:按鈕點擊
const throttleButton = document.getElementById('throttle-button');
const throttleResult = document.getElementById('throttle-result');
let clickCount = 0;
// 點擊處理函數(shù)
function handleClick() {
clickCount++;
throttleResult.innerHTML = `點擊次數(shù):${clickCount}`;
}
// 使用節(jié)流包裝點擊處理函數(shù)
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);
});
// 節(jié)流對比
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('防抖與節(jié)流演示頁面加載完成!');
console.log('防抖:在事件觸發(fā)后等待指定時間再執(zhí)行,如果在等待時間內再次觸發(fā),則重新計時。');
console.log('節(jié)流:在指定時間內只執(zhí)行一次,無論事件觸發(fā)多少次。');
});4.我的結果演示:
初始頁:

1.防抖演示
當我在二者都啟用時,先從防抖開始,根據(jù)防抖一般應用于反復搜索、注冊等場景,這里是使用了反復搜索的場景。當我隨意搜索一些內容時,只有停止輸入一段時間后(顯示正在搜索“”)后才執(zhí)行搜索(模擬真實搜索場景),避免頻繁請求,你想假如沒有這個的話,你反復輸入或回車搜索,它就會不斷發(fā)送搜索請求,造成大量卡頓,而防抖就是為了防止這樣場景發(fā)生。用戶輸入時,通過防抖減少API請求次數(shù)(避免輸入過程中每次按鍵都請求)。


2.節(jié)流演示
根據(jù)節(jié)流一般應用于滾動事件、鼠標移動事件、按鈕快速點擊、動畫效果的場景。這里實驗用的是按鈕快速點擊事件,當我快速點擊按鈕時,“節(jié)流”會限制每秒最多執(zhí)行一次點擊事件,避免重復處理。主要就是按鈕防重復點擊 :通過節(jié)流限制點擊頻率(避免用戶快速點擊導致重復提交)。正常我們設置點擊按鈕,根據(jù)點擊來計算點擊次數(shù),這個是存粹計算點擊次數(shù),但我們在實際應用的時候,你反復點擊一個按鈕可能會導致導致重復提交,造成資源損耗卡頓,而這是通過時間來限制點擊次數(shù),1s內點擊一次才有效,1s內點擊多次都不計數(shù)無效,無效。

5.對比總結
防抖(Debounce)和節(jié)流(Throttle)是前端開發(fā)中抽象的性能優(yōu)化概念,test1通過 直觀的交互演示 將其具體化:
- 防抖演示 :搜索框輸入時,只有停止輸入一段時間后才執(zhí)行搜索(模擬真實搜索場景),避免頻繁請求。
- 節(jié)流演示 :快速點擊按鈕時,限制每秒最多執(zhí)行一次點擊事件,避免重復處理。
實驗的核心意義在于 建立前端性能優(yōu)化的思維 :
- 高頻事件( input 、 click 、 scroll 、 resize )會觸發(fā)大量函數(shù)調用,導致頁面卡頓。
- 防抖/節(jié)流通過 限制函數(shù)執(zhí)行頻率 ,減少不必要的計算和DOM操作,提升頁面流暢度。
- 實驗通過控制臺輸出和結果顯示,讓開發(fā)者直觀感受優(yōu)化前后的性能差異。
到此這篇關于通過代碼實驗演示js防抖與節(jié)流的文章就介紹到這了,更多相關js防抖與節(jié)流內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
typescript中 declare global 關鍵字用法示例小結
在TypeScript中,declare global 用于在模塊內部擴展全局作用域,本文重點介紹typescript中 declare global 關鍵字用法示例小結,感興趣的朋友跟隨小編一起看看吧2024-04-04
基于JavaScript實現(xiàn)在新的tab頁打開url
這篇文章主要介紹了基于JavaScript實現(xiàn)在新的tab頁打開url 的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-08-08
js根據(jù)給定的日期計算當月有多少天實現(xiàn)思路及代碼
根據(jù)給定的日期計算當月有多少天,想必這樣的功能大家都想實現(xiàn)吧,所以本文的出現(xiàn)相當有必要,接下來看下實現(xiàn)代碼,感興趣的朋友可以了解下,希望對你有所幫助2013-02-02

