blog-web/source/_posts/JavaScript/函数防抖与函数节流.md
2019-03-12 17:01:44 +08:00

94 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 函数防抖与函数节流
date: 2019-3-12 15:28:41
tags:
- JavaScript
- 函数
categories:
- JavaScript
---
`函数防抖``函数节流`都是应用在该函数绑定的事件(比如keyup scroll等)可能在短时间内被频繁调用的情况
应用后可以有效提升性能, 从而优化页面流畅度
<!-- more -->
### 防抖debounce
在事件被触发n秒后再执行回调函数如果在这n秒内又被触发则重新计时
比如事件在9:00被触发, 设定在10秒后执行回调函数
之后在9:03的时候该事件再次被触发, 那么回调函数将会在9:13执行(原本会在9:10执行的回调函数不会执行)
如果在此期间事件再次被触发, 则回调函数执行事件继续向后推移
#### 代码模拟实现
```javascript
(function(){
function callback(content) {
console.log('这里是需要执行的回调函数' + content)
}
function debounce(fun, delay) {
return function(){
//获取函数的作用域和形参
let that = this
let args = arguments
clearTimeout(fun.id)// 清除定时器
fun.id = setTimeout(function () {
fun.apply(that, args)
}, delay)
}
}
// 这里设定的函数防抖时间为1s
let debounceAjax = debounce(callback, 1000)
document.getElementById('test-input').addEventListener('keyup', function (e) {
debounceAjax(e.target.value)
})
})()
```
实际的效果就是在输入框当中输入内容, 当输入动作停止1秒后才会执行callback
而不是输入一个字符就执行一次
#### 原理
防抖是创建一个定时器规定在delay时间后触发函数
但是在delay时间内再次触发的话都会清除当前的定时器重新计时。这样一来只有最后一次操作事件才被真正触发。
### 节流throttle
规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
比如事件在9:00被触发, 设定时间单位是10秒
之后在9:03的时候该事件再次被触发, 那么本次触发就是无效的
在9:00~9:10期间事件再次被触发, 均是无效的
#### 代码模拟实现
```javascript
(function(){
function callback(content) {
console.log('这里是需要执行的回调函数' + content)
}
function throttle(fn, delay) {
let lastTime
let timer
delay = delay || 300 // 默认间隔为300ms
return function() {
let context = this
let args = arguments
let nowTime = +new Date()// 获取系统当前时间戳
if (lastTime && nowTime < lastTime + delay) { // 当前距离上次执行的时间小于设置的时间间隔
clearTimeout(timer)// 清除定时器
timer = setTimeout(function() { // delay时间后执行函数
lastTime = nowTime
fn.apply(context, args)
}, delay)
} else { // 当前距离上次执行的时间大于等于设置的时间,直接执行并且记录本次执行的时间戳
lastTime = nowTime
fn.apply(context, args)
}
};
}
let throttleAjax = throttle(callback, 1000)
document.getElementById('test-input2').addEventListener('keyup', function (e) {
throttleAjax(e.target.value)
})
})()
```
### 应用场景举例
节流: 提交按钮的防重点
防抖: input框对输入内容的自动联想