目录
1 防抖
1.1 概念
1.2 应用场景
1.3 lodash防抖
1.4 手写防抖
2 节流
2.1 概念
2.2 应用场景
2.3 lodash节流
2.4 手写节流
2.5 记录视频上一次的播放位置
1 防抖
1.1 概念
防抖就是让事件触发后延迟n秒后再执行回调函数,在这n秒内如果事件又被触发,则重新计时(再等n秒后触发)
- 相当于英雄联盟按回城后需要等待几秒才能成功,如果进行了别的操作之后再按一下回城就重新计时
防抖的目的有两个
- 怕用户按错了,按错了达到了一个不想要的结果前给你一个可以取消的时间,还是以回城举例,按了一下回城,等几秒,这几秒你发现按错了,你就可以移动一下或者进行别的什么操作取消回城
- 频繁触发同一个事件只需要在确定结果后执行一遍回调函数,比如一些搜索框的建议,如果不做防抖,那么你的每一次输入都会给你一次建议,如果做防抖就会在你输入完毕后只给你一次建议
1.2 应用场景
输入框防抖,比如验证用户名是否可用,用户输入完成后过一段时间(1秒),我们再发起请求 附录5-淘宝搜索案例_Suyuoa的博客-CSDN博客
1.3 lodash防抖
我们使用lodash的debounce(),debounce()会返回一个新函数
加之前是这样的
这样在键盘抬起来的时候就会出现后面的字
加之后是这样的
最后一次键盘按键抬起来后等500ms后才会出现后面的字
1.4 手写防抖
手写防抖的常用方式是使用定时器,在事件开始的时候使用clearTimeout(),之后给回调函数setTimeout()
最后一次keyup 500ms后才会出现执行结果
我们简单封装一下方便复用
2 节流
2.1 概念
节流是在n秒内无论执行多少次也只当作执行一次,比如在moba游戏中,你一直右键点击敌人,但攻击的动作是由攻速限制的。比如你1s能打1次,你在1s内点多少次鼠标也只能打一次。
节流的目的主要就是降低事件的触发频率
节流的常用方式是搞一个节流阀(一个变量给布尔值),在轮播图中我们使用过
2.2 应用场景
在轮播图的左右点击按钮我们会用到节流,令其如果在n秒内点击了多次只切换一次 37.轮播图_Suyuoa的博客-CSDN博客
抢购的按钮,理论上点击一次发送一次,但是如果用户搞个连点器你的服务器吃不住
视频中介绍了一个图片跟随鼠标的节流例子也可以很直观的看出节流的区别,感兴趣可以看一下 12.案例-使用节流优化案例效果_哔哩哔哩_bilibili 在视频中的例子并不是一个布尔变量,而是一个定时器定了一个极短的时间(16ms)让人眼看不出来区别。
2.3 lodash节流
没加之前是这样的,每点击一下都+1
我们使用lodash中的throttle()加上节流,第一个参数是要执行的函数,第二个参数是多长时间才能开启下一次操作,我们这里设置间隔为1s,返回值为一个新函数
这样虽然可以点击,但前后点击1s才是有效点击
2.4 手写节流
经测试,每隔1s才能实现有效点击
也可以不使用throttle_flag只使用throttle_timer这个变量
- 这里(在开启定时器的时候)不能使用clearTimeout()清除定时器,使用clearTimeout()清除过后,throttle_timer的值不是null
经测试效果与上面相同
2.5 记录视频上一次的播放位置
需要用到下面两个事件,简单理解一下就是 ontimeupdate 在视频播放的时候触发,onloadeddata 在视频打开的时候触发
video标签中的currentTime是一个可读写的属性,我们在播放的时候每隔1s记录视频当前的事件,之后在打开的时候把这个时间给回video标签(如果是第一次打开我们给默认的0)
由于ontimeupdate的更新频率过快(1s好多次),我们没必要这么快(1s一次就行),所以可以对其进行节流
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<video src="./test.mp4" controls></video>
</body>
<script>
function throttle(fn,time) {
let throttle_timer = null
return function() {
if (!throttle_timer) {
fn()
throttle_timer = setTimeout(function() {throttle_timer = null},time)
}
}
}
const video = document.querySelector('video')
video.addEventListener('timeupdate',throttle(function(){localStorage.setItem('video_time',video.currentTime)},1000))
video.addEventListener('loadeddata',function() {video.currentTime = localStorage.getItem('video_time') || 0})
</script>
</html>
我们现在看到了2s的位置
刷新后发现视频从2s处开始播放