手写一个事件防抖函数

防抖:

事件响应函数在一定时间后执行,如果在这段时间内再调用,则重新计算执行时间;实现原理为设置一个定时器,约定在xx毫秒后再触发事件处理,每次触发事件都会重新设置计时器。

防抖应用场景:

scroll事件滚动触发,搜索框输入查询,表单验证,按钮提交事件,浏览器窗口缩放,resize事件。

为什么要防抖?

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .content {
            width: 800px;
            height: 400px;
            background-color: aqua;
            margin: 100px auto;
        }
    </style>
</head>

<body>
    <div class="content"></div>
    <script>
        // 频繁触发
        let count = 0;
        let content = document.querySelector('.content');

        function doSome() {
            content.innerHTML = count++;
        }

         content.onmousemove = doSome;
    </script>
</body>

</html>

上面的代码想要实现功能:当鼠标移入到content里面,让count+1。但是真实实现的功能是鼠标移动一下count就会进行+1操作。比如实现一个搜索框功能,如果用户每输入一个字,就向服务器提交一次请求,这会页面出现卡顿,影响用户体验。而我们想要实现的是用户输入完内容,才向用户提交请求。这时就用到了防抖。

一个防抖和节流的插件underscore.js,可以实现函数的防抖和节流。

使用方法:

先引入js文件,然后使用_.debounce(函数名, 延迟时间,是否立即执行(默认为true))实现

content.onmousemove = _.debounce(doSome, 1000);

手写一个防抖函数debounce.js

// 防抖的函数
function debounce(func, wait, immediate) {
    let timeout, result;
    let decounced = function() {
        let that = this;
        let args = arguments;
        if (timeout) { clearTimeout(timeout); }
        if (immediate) {
            let callNow = !timeout;
            timeout = setTimeout(() => {
                    callNow = null;
                }, wait)
                // 立即执行
            if (callNow) {
                result = func.apply(that, args)
            }
        } else {
            // 不会立即执行
            timeout = setTimeout(function() {
                // 改变this指向,使其指向调用者
                // 拿到函数中的实参(event指向)
                func.apply(that, args)
            }, wait);
        }
        return result;
    }
    decounced.cancel = function() {
        clearTimeout(timeout);
        timeout = null;
    }
    return decounced
}

该函数直接引用,即可使用,此外也实现了取消防抖的功能。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .content {
            width: 800px;
            height: 400px;
            background-color: aqua;
            margin: 100px auto;
        }
    </style>
</head>

<body>
    <div class="content"></div>
    <button>取消防抖</button>
    <script src="./debounce.js"></script>
    <script>
        

        // 频繁触发
        let count = 0;
        let content = document.querySelector('.content');
        let btn = document.querySelector('button')

        function doSome() {
            content.innerHTML = count++;
            return 'hhhhh'
        }

       
        let doS = debounce(doSome, 10000);
        //    点击按钮取消防抖
        btn.onclcik = function() {
            doS.cancel()
        }
        content.onmousemove = doS;
    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/weixin_57399180/article/details/118020652