JS function anti-shake, throttling

1. What is function anti-shake

  For events that are triggered continuously in a short period of time ( onresize , scroll , mousemove  , mousehover  ), the function can only be executed once within n seconds after the event is triggered. If the event is triggered again within n seconds after the event is triggered, the function will be recalculated to delay the execution time

Two, how to solve

   Auxiliary implementation of setTimeout  to delay running the code that needs to be executed;

3. Specific code

// 防抖 短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。
/**
 * @desc 函数防抖
 * @param fn目标函数
 * @param delay 延迟执行
 * @param {Object} immediate
 */
function debounce(fn, delay, immediate) {
    if(typeof fn != "function") {
        throw new TypeError("fn不是函数")
    }

    let timer;
    return function() {
        var _this = this
        var args = arguments
        if(timer) {
            clearTimeout(timer)
        }

        if(immediate) { // 立即执行(触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数)
            let callnow = !timer
            timer = setTimeout(() => {
                timer = null
            }, delay)
            if(callnow) fn.apply(_this, args)
        } else { // 延迟执行(触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间)
            timer = setTimeout(function() {
                fn.apply(_this, args);
            }, delay)
        }
    }
}

input.addEventListener('keyUp', debounce(() => {
    console.log(input.value)
}, 600))

4. What is throttling

  After the function is executed once, the function will no longer work within the specified time period, and will not be effective again until this time has elapsed

5. Applicable scenarios

  Search box search input, change browser window size

6. Code implementation

1 // 节流
 2 /**
 3  * @param {Object} 函数节流
 4  * @param {Object} delay
 5  * @param {type} 1 表时间戳版,2 表定时器版
 6  * 时间戳版的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候
 7  */
 8 function throttle(fn, delay, type) {
 9     if (type === 1) {
10         let previous = 0;
11     } else if (type === 2) {
12         let timer;
13     }
14     return function() {
15         var _this = this;
16         var args = arguments;
17         if(type === 1) {
18             let now = Date.now();
19             if (now - previous > delay) {
20                 fn.apply(_this, args)
21                 previous = now
22             }
23         } else if(type === 2) {
24             if(timer) {
25                 return
26             }
27             timer = setTimeout(function() {
28                 fn.apply(fn, args)
30                 timer = null // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
31             }, delay)
32         }
33     }
34 }
35 
36 diva.addEventListener('drgs', throttle((e) => {
37     console.log(e.offsetX, e.offsetY)
38 }, 100))

Guess you like

Origin blog.csdn.net/codingLeader/article/details/122963598