一、什么是防抖,什么是节流
- 防抖:用户多次触发事件,当停止时将事件执行一次
- 节流:多次触发事件,在这个过程中每隔n秒执行一次
二、lodash中debounce函数的使用
1、安装
npm i --save lodash.debounce
2、导入
import debounce from 'lodash/debounce'
3、观察者模式防抖
<input type="text" v-model="value">
data() {
return { value: '' }
},
watch: {
value: {
handler(val) {
this.debounceWatch(val)
}
}
},
created() {
this.debounceWatch = debounce((val) => {
console.log(val)
}, 500)
},
beforeDestroy() {
this.debounceWatch.cancel()
}
4、给事件回调函数添加防抖
<input type="text" @input="handleInput">
created() {
this.handleInput = debounce((e) => {
console.log(e.target.value)
}, 500)
},
beforeDestroy() {
this.handleInput.cancel()
}
两种方式效果一样,如果是使用组件库,需要指定v-model
<el-input v-model="value" @input="handleInput" />
<van-field v-model='value' @input="handleInput" />
5、不推荐的写法
这样写会使函数的某个属性丢失,原因是methods中的方法会经过bind返回一个新的函数,此时原函数的属性在新函数中不存在
<template>
<input type="text" @input="handleInput">
</template>
<script>
import debounce from 'lodash/debounce'
export default {
methods: {
handleInput: debounce(function (val) {
console.log(val.target.value)
}, 200)
},
}
</script>
三、lodash中throttle函数的使用
1、安装
npm i --save lodash.throttle
2、导入
import throttle from 'lodash/throttle'
3、给事件回调函数添加节流
<input type="text" @input="handleInput">
created() {
this.handleInput = throttle((e) => {
console.log(e.target.value)
}, 500)
},
beforeDestroy() {
this.handleInput.cancel()
}
4、播放音频时,高亮对应的节点
this.wavesurfer.on('audioprocess', this.handleAudioprocess);
handleAudioprocess (currentTime) {
const regionList = Object.values(this.wavesurfer.regions.list);
const timeScopeList = regionList.map(({ start, end }) => ({ start, end }));
const index = timeScopeList.findIndex(({ start, end }) => start <= currentTime && currentTime <= end);
console.log(index);
this.active = index;
if (index !== -1) {
this.$refs.ulRef.scrollTop = index > 6 ? 36 * index : 0;
};
},
看啊,打印了好多次,咱们使用throttle优化一下:
// this.wavesurfer.on('audioprocess', this.handleAudioprocess);
this.wavesurfer.on('audioprocess', throttle(this.handleAudioprocess, 50));
使用throttle优化后,打印次数少多了
但其实这样写不推荐,推荐的写法是:
created () {
this.handleInput = throttle(this.handleAudioprocess, 50);
},
beforeDestroy () {
this.handleInput.cancel();
},
...
this.wavesurfer.on('audioprocess', this.handleInput);
四、防抖函数的实现
用来监听resize事件
window.addEventListener('resize', debounce(handle, 500))
function handle() {
console.log(document.body.clientWidth)
}
如果一直在触发resize,需要清除掉定时器,直到停下来后重新定义setTimeout,500ms后执行fn
function debounce(fn, delay) {
var timer = null
return function () {
if (timer) clearTimeout(timer)
var _this = this
var _arguments = arguments
timer = setTimeout(function () {
fn.apply(_this, _arguments)
}, delay)
}
}
五、节流函数的实现
通过setTimeout实现:
每隔500ms设置一次定时器,同时清除该定时器
function throttle(fn, delay) {
var timer = null
return function () {
var _this = this
var _arguments = arguments
if (!timer) {
timer = setTimeout(function () {
fn.apply(_this, _arguments)
clearTimeout(timer)
timer = null
}, delay)
}
}
}
通过时间戳实现:
在触发resize的过程中,当前时间减上一次时间如果大于等于500,执行一次fn,并且将上一次时间重置为当前时间
function throttle(fn, delay) {
var prevTime = Date.now()
return function () {
var curTime = Date.now()
if (curTime - prevTime >= delay) {
fn.apply(this, arguments)
prevTime = Date.now()
}
}
}