【JS】手写防抖

防抖分为立即执行版本非立即执行版本

代码示例

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>防抖</title>
</head>
 
<body>
 
</body>
<script>
    /**
    * @desc 函数防抖---“立即执行版本” 和 “非立即执行版本” 的组合版本
    * @param func 需要执行的函数
    * @param wait 延迟执行时间(毫秒)
    * @param immediate---true 表立即执行,false 表非立即执行
    **/
    function debounce(func, wait, immediate) {
        let timer;
 
        return function () {
            let context = this;
            let args = arguments;
 
            if (timer) clearTimeout(timer);
 
            if (immediate) {
                var callNow = !timer;
                timer = setTimeout(() => {
                    timer = null;
                }, wait)
                if (callNow) func.apply(context, args)
            } else {
                timer = setTimeout(function () {
                    func.apply(context, args)
                }, wait);
            }
        }
    }
 
    function handle() {
        console.log(Math.random());
    }
 
    window.addEventListener("mousemove",debounce(handle,1000,true)); // 调用立即执行版本
    // window.addEventListener("mousemove", debounce(handle, 1000, false)); // 调用非立即执行版本
</script>
</html>

 

防抖函数是单例的

由于闭包的特性,timer 只有一份,如果两个地方使用同一个防抖函数,状态会共享

<html>
    <head>
        <title>自定义封装防抖</title>
    </head>
    <body>
        <button onclick="debounceClick()">提交1</button>
        <button onclick="debounceClick()">提交2</button>
    </body>
    <script>
        function debounce(func, wait, immediate) {
            let timer
            return function() {
                const context = this
                const args = arguments
                console.log(`timer = ${timer}`)
                if(timer){
                    clearTimeout(timer)
                }
                if(immediate) {
                    const callNow = !timer
                    timer = setTimeout(() => {
                        timer = null
                    }, wait);
                    if(callNow) {
                        func.apply(context, args)
                    }
                } else {
                    timer = setTimeout(() => {
                        func.apply(context, args)
                    }, wait)
                }
            }
        }

        function click() {
            // print current time
            console.log(new Date().toString().split(' ')[4])            
        }

        const debounceClick = debounce(click, 1000, true)
    </script>
</html>

创建多个防抖函数

 

<html>
    <head>
        <title>自定义封装防抖</title>
    </head>
    <body>
        <button onclick="debounceClick()">提交1</button>
        <button onclick="debounceClick()">提交2</button>
        <button onclick="debounceClick2()">提交3</button>
    </body>
    <script>
        function debounce(func, wait, immediate) {
            let timer
            return function() {
                const context = this
                const args = arguments
                console.log(`timer = ${timer}`)
                if(timer){
                    clearTimeout(timer)
                }
                if(immediate) {
                    const callNow = !timer
                    timer = setTimeout(() => {
                        timer = null
                    }, wait);
                    if(callNow) {
                        func.apply(context, args)
                    }
                } else {
                    timer = setTimeout(() => {
                        func.apply(context, args)
                    }, wait)
                }
            }
        }

        function click() {
            // print current time
            console.log(new Date().toString().split(' ')[4])            
        }

        const debounceClick = debounce(click, 1000, true)
        const debounceClick2 = debounce(click, 1000, true)
    </script>
</html>

vue

<script setup lang="ts">
const p = console.log
function debounce(func: Function, wait: number, immediate: boolean): Function {
  let timer: any = null
  return function() {
    const context = this
    const args = arguments
    p(`timer: ${timer}`)
    if(timer) {
      clearTimeout(timer)
    }
    if(immediate) {
      const callNow = !timer
      timer = setTimeout(() => {
        timer = null
      }, wait)
      if(callNow) {
        func.apply(context, args)
      }
    } else {
      timer = setTimeout(() => {
        func.apply(context, args)
      }, wait)
    }
  }
}

function click() {
  console.log(new Date().getTime().toString().split(' ')[4])
}

const debounceClick: Function = debounce(click, 1000, true)
const debounceClick2: Function = debounce(click, 1000, true)
</script>

<template>
  <button @click="debounceClick">提交1</button>
  <button @click="debounceClick">提交2</button>
  <button @click="debounceClick2">提交3</button>
</template>

<style scoped>

</style>

 

posted @ 2023-09-06 20:31  zjy4fun  阅读(152)  评论(0编辑  收藏  举报