手写节流和防抖函数进阶版

手写节流和防抖函数

一、防抖函数

应用场景

  • 输入框中频繁的输入内容,搜索或者提交信息;
  • 频繁的点击按钮,触发某个事件;
  • 监听浏览器滚动事件,完成某些特定操作;
  • search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
  • window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

**原理:**在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

**大白话版原理:**小明答应在三天之后还钱给小红,但是小红在三天内如果再催小明还钱的话,则会重新开始计算这三天时间,只有三天内小红不催小明换钱,三天后小明才会还小红的钱

1.基础版防抖函数

简单的实现了防抖函数的功能

<!DOCTYPE html>
<head>
    <title>Document</title>
</head>
<body>
    <button>点击</button>
</body>
<script>
    let btn = document.querySelector('button')
    function debounce(fn, time) {
        let timer = null
        return function () {
            console.log(this); // <button>点击</button>
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                fn()
            }, time)
        }
    }
    btn.addEventListener('click', debounce(function () {
        console.log(this);  //window
        console.log('我被点击了');
    }, 1000))
</script>
</html>

2.优化this的指向

在基础版防抖函数中,在我们所写的防抖函数中this指向为我们所点击的标签,而在我们调用的时候this指向为window,有时候我们需要对原来的标签进行操作的话,此时我们需要改变this的指向来拿到原来的标签

<!DOCTYPE html>
<head>
    <title>Document</title>
</head>
<body>
    <button>点击</button>
</body>
<script>
    let btn = document.querySelector('button')
    function debounce(fn, time) {
        let timer = null
        return function () {
            console.log(this); // <button>点击</button>
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                fn.call(this, arguments)
            }, time)
        }
    }
    btn.addEventListener('click', debounce(function () {
        console.log(this); // <button>点击</button>
        console.log('我被点击了');
    }, 1000))
</script>
</html>

3.优化立即执行效果(第一次立即执行)

<!DOCTYPE html>
<head>
    <title>Document</title>
</head>
<body>
    <button>点击</button>
</body>
<script>
    let btn = document.querySelector('button')
    function debounce(fn, time, immediate = false) {
        let timer = null
        let isImmediate = false
        return function () {
            if (timer) clearTimeout(timer)
            if (immediate && !isImmediate) {
                fn.call(this, arguments)
                isImmediate = true

            } else {
                timer = setTimeout(() => {
                    fn.call(this, arguments)
                    isImmediate = false
                }, time)
            }

        }
    }
    btn.addEventListener('click', debounce(function () {
        console.log('我被点击了');
    }, 1000,true))
</script>
</html>

二、节流函数

节流的应用场景:

  • 监听页面的滚动事件;
  • 鼠标移动事件;
  • 用户频繁点击按钮操作;
  • 鼠标不断点击触发,mousedown(单位时间内只触发一次)
  • 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

**原理:**规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

**大白话版原理:**小明答应在三天之后还钱给小红,在这三天内小明无论催小明多少次还钱或者是不催,小明都会在三天后还钱给小红

1.基础版防抖函数

<!DOCTYPE html>
<head>
    <title>Document</title>
</head>
<body>
    <button>点击</button>
</body>
<script>
    let btn = document.querySelector('button')
    function throttle(fn, time,first=true) {
        let lastTime = 0
        return function () {
            const newTime = new Date().getTime()
            const remainTime = time - (newTime - lastTime)
            if (remainTime <= 0) {
                fn.call(this, arguments)
                lastTime = newTime
            }
        };
    }
    btn.addEventListener('click', throttle(function () {
        console.log(this.innerHTML += 1);
    }, 2000,true))
</script>
</html>

猜你喜欢

转载自blog.csdn.net/L1147484597/article/details/124358509