赞
踩
防抖和节流是优化 JavaScript 代码中事件处理函数的常用技巧。当一个事件被频繁触发时,防抖和节流能够限制事件处理函数的执行次数,从而避免性能问题。
## 1. 防抖
防抖的基本思想是:当事件被触发时,延迟一段时间再执行事件处理函数,如果在延迟时间内事件再次被触发,则重新开始计时。这样能够避免事件处理函数被频繁调用的问题,提高页面性能。
### 1.1 基本实现
下面是一个基本的防抖实现:
```javascript
function debounce(func, delay) {
let timer = null;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
```
这个实现的思路是:每次事件被触发时,清除之前的计时器,并重新设置计时器。只有当计时器超过指定的延迟时间后才执行事件处理函数。
### 1.2 使用示例
下面是一个使用防抖优化搜索框输入事件的例子:
```html
<input type="text" id="search-input" />
<script>
const searchInput = document.getElementById("search-input");
function search() {
// 模拟搜索操作
console.log("search: ", searchInput.value);
}
const debounceSearch = debounce(search, 500);
searchInput.addEventListener("input", debounceSearch);
</script>
```
这个例子中,当用户在搜索框中输入文字时,会触发`input`事件。通过使用`debounce`函数将事件处理函数`search`包装为一个防抖函数`debounceSearch`,可以避免事件处理函数被频繁调用的问题。
## 2. 节流
节流的基本思想是:当事件被触发时,在一定时间内只执行一次事件处理函数。如果在这段时间内事件被多次触发,只有第一次触发的事件会执行事件处理函数,后续的事件会被忽略。
### 2.1 基本实现
下面是一个基本的节流实现:
```javascript
function throttle(func, interval) {
let lastTime = 0;
return function() {
const currentTime = Date.now();
if (currentTime - lastTime > interval) {
func.apply(this, arguments);
lastTime = currentTime;
}
};
}
```
这个实现的思路是:每次事件被触发时,记录当前时间`currentTime`,如果`currentTime`与上一次执行事件处理函数的时间`lastTime`的时间差大于指定的时间间隔`interval`,则执行事件处理函数,并更新`lastTime`。
补充说明:
防抖和节流都是为了解决频繁触发事件导致性能问题的问题,具体来说:
- 防抖:在短时间内频繁触发某个事件时,只执行最后一次操作,可以防止在操作未完成时又执行了下一次操作,从而避免频繁触发事件导致的性能问题。
- 节流:在短时间内频繁触发某个事件时,每隔一段时间执行一次操作,可以保证事件处理的平稳进行,避免一次性处理大量事件导致的性能问题。
下面分别详细介绍一下防抖和节流的实现方法和使用场景。
防抖
防抖的实现方法有两种:时间戳和定时器。
时间戳实现:
```javascript
function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
const timestamp = Date.now();
if (timeout) clearTimeout(timeout);
if (timestamp - debounce.lastTime > wait) {
func.apply(context, args);
debounce.lastTime = timestamp;
} else {
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
}
}
}
debounce.lastTime = 0;
```
定时器实现:
```javascript
function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
}
}
```
使用场景:
- input搜索框,输入内容停止一段时间后再进行搜索请求。
- 拖拽功能,放手后执行最后一次操作。
- 窗口缩放,停止一段时间后再触发事件。
节流
节流的实现方法有两种:时间戳和定时器。
时间戳实现:
```javascript
function throttle(func, wait) {
let lastTime = 0;
return function() {
const context = this;
const args = arguments;
const timestamp = Date.now();
if (timestamp - lastTime > wait) {
func.apply(context, args);
lastTime = timestamp;
}
}
}
```
定时器实现:
```javascript
function throttle(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
if (!timeout) {
timeout = setTimeout(function() {
func.apply(context, args);
timeout = null;
}, wait);
}
}
}
```
使用场景:
- 滚动加载,每隔一段时间判断一次是否需要加载数据。
- 监听浏览器窗口resize事件,每隔一段时间触发一次事件。
- 鼠标移动,每隔一段时间才执行一次操作。
注意:防抖和节流都是通过闭包来实现的,所以要注意内存泄漏的问题,及时清除无用的
总结:
防抖和节流是两种优化高频触发事件的方法,它们都是通过延迟函数的执行来减少函数调用的次数,提高页面的性能和流畅度。
防抖是在一定时间内多次触发事件时只执行一次函数,而节流是在一定时间内多次触发事件时,只执行一次函数并且是在定时器的时间间隔内执行的。
在实际开发中,我们需要根据具体的需求来选择使用哪种方式进行优化。例如,在处理高频触发的事件时,比如scroll
、resize
、mousemove
等,我们可以使用节流来优化,而在处理输入框的输入事件时,我们可以使用防抖来优化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。