防抖(debounce):n秒后在执行该事件,若在n秒内被重新触发,则重新计时。比如:表单提交,一秒钟点击多次,提交按钮会在短时间被多次触发,使用防抖函数就可以让按钮在一定的时间内只触发一次或者自动感应门,当A进入,门感应有人,被触发,门打开,5秒后门关闭。如果同时B进入,这时门就重新进入5秒倒计时关闭
节流(throttle):n秒内只运行一次,若在n秒内重复触发,只有一次生效。比如:鼠标滚动刷新页面,规定时间五秒执行一次刷新,无论五秒内滚动几次,只执行一次刷新,五秒后滚动,再进行刷新。事件过程就是触发事件-执行任务-设置时间间隔。时间间隔内有触发行为 就取消任务,时间间隔后有触发行为,就再次执行任务和设置时间间隔
防抖代码
使用场景
防抖:改变页面大小的统计,滚动页面位置统计,输入框连续输入的请求次数控制
知识点:
1.高阶函数,就是函数中可以传入另一个函数作为参数的函数
2.addEventListener() 方法用于向指定元素添加事件句柄。(提示: 使用 removeEventListener() 方法来移除 addEventListener() 方法添加的事件句柄。)
四个难点:
1.定义监听函数,不使用高阶函数,会导致防抖函数直接执行
使用高阶函数,即使执行了这个防抖函数,但是这个防抖函数返回了一个函数在点击事件触发的时候才执行
2.需要先清理延时(clearTimeout),再进行延时操作(setTimeout)
3.作用域链(闭包),需要把timer定义在return函数外部,使创建延时(let timer),清楚延时(clearTimeout),延时操作(setTimeout)建立联系。若果全部写在return内部,那么清除延时就不起作用了。
当我们把timer放在返回函数外围,那么定义监听函数的时候就同时定义了这个timer变量(页面初始化就执行debounce,只初始化一次timer,进行点击方法才会继续执行返回函数),然后通过返回函数不断给timer赋值进行延时,每一个清楚延时,就是清除上一个定义的延时,相当于多个函数,公用一个外部变量
4.this的指向问题,防抖函数中this指向window是不对的,应该指向操作的对象。可以使用箭头函数解决,也可以在返回函数中先保存this,使用call(),apply(),bind()都可以来重新定义this对象
节流代码
闭包问题
使用场景
鼠标滚动列表刷新
知识点:
1.resize改变页面尺寸事件