防抖原理

事件响应函数在一段时间后才执行,如果这段时间内再次调用,则重新计算执行时间。
意思是如果在规定的时间内无论你怎么触发事件都不会执行,只有在最后一次触发事件后并且在规定的时间内无触发事件操作才会执行。

防抖原理举例(这里以点击按钮为例):

  • 设置防抖的时间为2秒;
  • 点击一次按钮,则开始倒计时;
  • 如果在2秒内再次点击按钮,则重新从2秒开始倒计时;
  • 如果2秒过后没有再点击按钮,则执行点击按钮对应的事件,否则就再次从2秒开始倒计时。

代码实现(这里以点击按钮为例)

实现过程讲解(使用定时器实现):

  1. 给按钮添加点击事件;
  2. 当用户点击按钮后,先使用clearTimeout清除延时操作;
  3. 然后使用setTimeout设置延时操作;
  4. 如果在规定时间内再次点击按钮,则回到第二步;
  5. 如果在规定时间内没有点击按钮,则执行按钮对应的事件函数。
代码实现
<body>
    <button>付款</button>
    <script>
    	// 获取button按钮元素
        const btn = document.querySelector("button");
        // 定义付款操作函数
        function payMoney() {
        	console.log("付款成功");
        }
        // 定义防抖函数
        // func: 点击按钮要执行的函数
        // delay: 防抖时间
        function debounce(func, delay) {
        	// 设置定时器标识
        	let timer;
        	// 难点返回事件绑定函数
        	return function() {
        		// func指定this
        		let context = this;
        		// func参数
        		let args = arguments;
        		// 先清除定时器
        		clearTimeout(timer);
        		//设置定时器
        		timer = setTimeout(() => {
        			// 调用函数
        			func.apply(context, args);
        		}, delay);
        	}
        }
		// 绑定点击事件
		btn.addEventListener("click", debounce(payMoney, 1000))
    </script>
</body>

这样一个防抖函数就完成了!
不过有几个难点小shy需要在这里说明下
难点1:debounce函数不能直接调用func函数,因为按钮绑定的事件函数是直接调用的,所以需要返回一个函数;

难点2:每次点击先清除延时操作,clearTimeout不能清除一个没有定义的变量名,所以需要先定义一个变量timer用来清除和定义延时操作;

难点3:如果要让这些独立的执行函数有联系就需要在函数外面定义timer;

难点4:调用函数func,容易忽略this指向,需要将this指向调用者。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐