概叙:
开发中,经常会遇到以下场景:监听鼠标移动 onmousemove,监听页面滚动 onscroll,监听大小变化 onresize,监听 input 输入,按钮的搜索、提交功能等。这些场景下,事件会被频繁触发,但我们并不想事件被频繁触发,这时就需要通过防抖和节流来限制频繁操作。
防抖和节流都是为了解决事件频繁触发的问题,但在实现原理上有些不同,具体实现原理看下文。
一、防抖(debounce)
1、原理:
当持续触发事件时,在一定时间内没有再触发事件,事件才会处理函数一次,如果在设定的时间到来之前,又触发了事件,则重新开启定时器,执行最后一次触发事件。
2、应用场景:
scroll事件滚动 浏览器窗口的缩放resize事件 搜索框输入查询的时候 表单验证 按钮的提交事件 3、代码:
function debounce (fn, delay = 1000) { let time = null return function () { // 获取当前this let that = this // 判断是否已经存在,如果存在直接清除 if (time) { clearTimeout(time) } time = setTimeout(() => { // 使fn 中this,执行当前调用者,并传入参数 fn.apply(that, arguments) }, delay) } } // 测试demo function logger(e){ console.log('log -----') } btn.addEventListener('click',debounce(logger, 1000))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 二、节流(throttle)
1、原理:
在持续触发事件时,在一定时间内只调用一次函数,如果在规定时间内,再次触发此事件,则直接忽略不执行,其主要目的就是减少一段时间的触发频率
2、应用场景:
DOM元素拖拽功能实现 计算鼠标移动距离 监听scroll滚动事件 搜索、提交等按钮功能 3、代码:
function throttle (fn, delay = 1000) { let time = null; return function () { let that = this; // 如果已经存在定时器了,则 不做处理 if (!time) { time = setTimeout(() => { fn.apply(that, arguments); // 完结时,将time改为null time = null; }, delay); } }; }