Usage scenarios
Onresize; window.onscroll; window.onscroll; window.onresize; window.onscroll Prevent frequent triggering
Image stabilization
Definition: When an event is triggered several times in a row within a period of time, only the last event is executed. If the event is triggered again within the set interval, the timer is cleared and the timer is restarted.
Example: If the Scroll event is triggered continuously, handle is not executed immediately. If the click event is not triggered again within 1s, handle code is executed:
Add stabilization with addEventListener
created() {
window.addEventListener('resize'.this.debounce(this.fn, 500))},methods: {
debounce (fn, wait) {
let timer = null
return () = > {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(fn, wait)
}
},
fn () {
console.log(Math.random())
}
}
Copy the code
There is no closure and the timer is unique, giving only one button the benefit of adding a closure: no global variables are generated and can be reused
// The anti-shake method is introduced from outside
<el-button @click="debounce(fn, 1000)">test</el-button>
// utils.js
Vue.prototype.debounce = function (fn, wait) {
if (window.timer2) {
clearTimeout(window.timer2)
}
window.timer2 = setTimeout(fn, wait)
}
// The anti-shake method is in the current file
<el-button @click="debounce(fn, 1000)">test</el-button>
debounce (fn, wait) {
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(fn, wait)
},
fn () {
console.log(Math.random())
}
Copy the code
Of the closure form:
// The anti-shake method is introduced from the outside
Vue.prototype.yyy = (fn, delay = 1000) = > {
let timer = null
return (. params) = > {
const context = this
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() = > {
fn.apply(context, params)
}, delay)
}
}
created() {
this.zzz = this.yyy(this.fn)
}
<el-button @click="zzz(1)">test</el-button>
// The anti-shake method is in the current page
// Pass fn to closure, undefined
Copy the code
The key is to get the method A returned by the Debounce method, which is bound to the event.
Recommended usage:
- I’m going to write it outside in closure form, and I’m going to introduce
- Global instruction form
Global directive form specific code: directive/ debelas.js
import { debounce } from '@/utils'
export default {
inserted: function(el, binding, vnode) {
let [fn,wait,immediate,event = "click"] = binding.value
el.addEventListener(event, debounce(
fn,
wait,
immediate
).bind(vnode))
}
}
Copy the code
directive/index.js
import debounce from './debounce'
const install = function (Vue) {
Vue.directive('debounce', debounce)
}
debounce.install = install
export {
debounce
}
Copy the code
main.js
import {debounce} from './directive'
debounce.install(Vue)
Copy the code
Test.vue
<el-button v-debounce="[fn]">test</el-button>
fn () {
console.log(Math.random())
}
Copy the code
The throttle
Definition: When an event is triggered for multiple times in a period of time, the event can be executed only once in each interval. Example: If the Scroll event is triggered continuously, handle is not executed immediately. Handle is executed once every 1s. Code:
export const throttle = (fn: Function, delay = 2000) = > {
let preTime = Date.now()
return (. params: any[]) = > {
const context = this
let doTime = Date.now()
if (doTime - preTime >= delay) {
fn.apply(context, params)
preTime = Date.now()
}
}
}
Copy the code