防抖: 防抖是指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。(就是在触发某个事件后,在下一次触发之前,中间的间隔时间如果超过设置的时间才会发送请求,一直触发就不会发送请求)
应用场景:
-
scroll事件滚动触发,
-
搜索框输入查询
-
表单验证
-
按钮提交事件
-
浏览器窗口缩放,resize事件
代码示例
function scrollHandler() { console.log('滚动了')}window.addEventListener('scroll', scrollHandler)function debounce(fn, wait) { var timeout //闭包的方式定义一个全局变量,是实现防抖函数的核心 return function () { var context = this, args = arguments clearTimeout(timeout) timeout = setTimeout(function () { fn.apply(context, args) }, wait) }}window.addEventListener('scroll', debounce(scrollHandler, 500))理解难点:
a)逻辑过程是, 定义一个setTimeout事件, 假如在触发之前,又发生了scroll事件的话, 通过clearTimeout函数清除之前定义的setTimeout事件,同时又再次定义一个setTimeout定时事件,从而达到防抖的功能。 b) debounce(scrollHandler, 500),这句代码返回的是一个函数,并没有显式传递参数进去,为什么还要特意用args = arguments这句话特意的接受一下参数, 原因是因为js引擎会自动的传递event事件参数,所以用args = arguments这句话是为了接受event等默认传递的参数。
花边:
- 常见操作
- 复杂操作
节流: 节流是指如果持续触发某个事件,则每隔n秒执行一次。
主要应用场景:
-
DOM元素的拖拽功能实现
-
射击游戏类
-
计算鼠标移动的距离
-
监听scroll事件
代码示例
function throttle(fn, wait) { let timeout; return function () { let context = this let args = arguments if (!timeout) { timeout = setTimeout(function() { timeout = null fn.apply(context, args) }, wait) } }}理解难点:
基本的逻辑是对timeout进行判断, 只有为空才能设置setTimeout事件,从而达到了一个周期只执行一次回调函数的功能,不过这个函数,并没有立即执行的功能。
花边:
- 常见操作
- 复杂操作
总结
函数节流与函数防抖都是为了限制函数的执行频次,都是一种性能优化的方法。区别是防抖是有条件的周期性动作,而节流是无条件的周期性动作。两者实现的核心都依赖于闭包
学习链接