The anti-shake and throttling functions are generally used in some high-frequency triggered methods, such as the input event of the associative input of the search box, onMousemove event, click event and so on. In fact, the service does not need to be triggered more than once, so it needs to be handled with anti-shake or throttling.

The simple way to think about it is this

Anti – shake function: click the button crazily, each time the time interval is less than the specified time, then the corresponding method will not be executed

Throttling function: click the button crazily and trigger the corresponding method only once within a specified time interval

The difference between immediate execution and non-immediate execution is that the immediate execution executes the state triggered for the first time and the non-immediate execution executes the state triggered for the last time

Image stabilization

code

 let Debounce = function (fn, delay = 300, immediate = false) {
    let timer = null // Closures store setTimeout state
    return function () {
        let self = this // Event source this
        let args = arguments // Receive the event from the event source
        if (timer) clearTimeout(timer) // Clear the fn timer if it exists
        if (immediate) { // Execute immediately
            letcallNow = ! timer// Execute the fn state
            timer = setTimeout(function () {
                timer = null
            }, delay)
            if (callNow) fn.apply(self, args)
        } else { // Not immediately executed
            timer = setTimeout(function () { // Or use the arrow function to point this to the DOM
                fn.apply(self, args)
            }, delay)
        }
    }
}

let con1 = document.querySelector('.con1')
let con2 = document.querySelector('.con2')
let con3 = document.querySelector('.con3')

let addNum = function (args) {
    console.log(this, args)
    this.innerText = (+this.innerText) + 1
}

con1.onmousemove = addNum / / no image stabilization

con2.onmousemove = Debounce(addNum) / / image stabilization

con3.onmousemove = Debounce(addNum, 300.true) // Stop shaking (immediately executed)
Copy the code

Effect of contrast

The throttle

code

// Base version throttling
let Throttle = function (fn, delay = 500) {
    let flag = true
    return function () {
        let self = this
        let args = [...arguments]
        if(! flag)return
        flag = false
        setTimeout(function () {
            fn.apply(self, args)
            flag = true
        }, delay)
    }
}

let con1 = document.querySelector('.con1')
let con2 = document.querySelector('.con2')

let addNum = function (args) {
    console.log(this, args)
    this.innerText = (+this.innerText) + 1
}

con1.onmousemove = addNum / / no throttling

con2.onmousemove = Throttle(addNum, 1000) / / throttling
Copy the code

Effect of contrast

Another way of writing the throttling function, the anti-shake function can also use a timestamp as a judgment condition

// Time interval as a judgment
let ThrottleTime = function (fn, delay = 500) {
    let preTime = 0 // Record the last execution time
    return function () {
        let self = this.// keep this at execution time
            args = [...arguments], // An argument passed in at execution time
            nowTime = +new Date(a)// Record the current time
        if (nowTime - preTime >= delay) {
            preTime = nowTime // Update the execution time
            fn.apply(self, args)
        }
    }
}
Copy the code

Plus immediate execution state

// Whether to execute immediately
let ThrottlePro = function (fn, delay = 500, immediate = false) {
    let preTime = 0 // Record the last execution time
    return function () {
        let self = this.// keep this at execution time
            args = [...arguments], // An argument passed in at execution time
            nowTime = +new Date(), // Record the current time
            flag = nowTime - preTime >= delay // Execute the command
        if (immediate) { // Whether to execute immediately
            if(! flag)return
            preTime = nowTime // Update the execution time
            fn.apply(self, args)
        } else {
            if(! flag)return // The execution condition is not met
            preTime = nowTime
            setTimeout(function () {
                fn.apply(self, args)
            }, delay)
        }
    }
}
Copy the code

Related links:

Eight steps to develop a VUE component library

JS common deep, shallow copy

VUE implementation principles (data hijacking, observer pattern)

Javascript implements simple bubble sort, insert sort

A very simple publish-subscribe model