写这篇文章主要用于自己以后查漏
防抖和节流的共同点:限制函数的执行频率,以优化函数触发频率过高而导致响应速度跟不上触发频率,出现延迟、假死、卡顿现象
区别:函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而防抖只是在最后一次事件触发后才执行一次事件处理函数
1、防抖:对于短时间内连续触发的事件(scroll,resize,click,,,,,),在某个时间期限内,事件处理函数只执行一次,即将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发
场景:在第一次触发事件(比如click)时,不立即执行处理函数handler,而是给出一个期限delay,然后
1)在delay内,没有在触发事件click,那么就执行处理函数handler
2)若在delay内再次触发事件click,那么当前计时取消,重新计时
效果:短时间内大量触发同一事件click,只会执行一次处理函数handler
缺点:如果事件在规定时间内被不断触发,则处理函数handler则会被不断延迟
实现方式:每次事件触发时设置一个延迟调用方法,并且取消之前的延时调用方法---利用setTimeout和必包实现
<template>
<div>
<img alt="Vue logo" src="./assets/logo.png">
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
<div class="btn" @click.stop.prevent="clickEvent">click</div>
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
// HelloWorld
},
data() {
return {
clickNum: 0,
timer: null
}
},
methods: {
clickEvent() {
this.debunce(this.handler, 2000)
},
debunce(handler, delay) {
// handler需要防抖的函数,delay防抖期限值
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
handler.apply(this, arguments)
}, delay)
},
handler() {
this.clickNum += 1
console.log('clickNum: ', this.clickNum)
}
}
}
</script>
<style>
html{
font-size: 200px;
}
#app {
font-size: 16px;
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
.btn{
background: gray;
color: yellow;
width: 0.5rem;
height: 0.5rem;
text-align: center;
line-height: 0.5rem;
font-size: .13rem;
}
</style>
2、节流:一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
<div class="btn" @click.stop.prevent="clickEvent">click</div>
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
// HelloWorld
},
data() {
return {
clickNum: 0,
valid: true,
timer: null
}
},
methods: {
clickEvent() {
this.throttle(this.handler, 2000)
},
throttle(handler, delay) {
// handler需要防抖的函数,delay防抖期限值
if (!this.valid) {
return false
}
this.valid = false
this.timer = setTimeout(() => {
clearTimeout(this.timer)
this.valid = true
handler.apply(this, arguments)
}, delay)
},
handler() {
this.clickNum += 1
console.log('clickNum: ', this.clickNum)
}
}
}
</script>
<style>
html{
font-size: 200px;
}
#app {
font-size: 16px;
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
.btn{
background: gray;
color: yellow;
width: 0.5rem;
height: 0.5rem;
text-align: center;
line-height: 0.5rem
}
</style>