防抖
防抖是什么?
单位时间内,频繁触发事件,只执行最后一次
通俗易懂点就是把防抖想象成MOBA游戏的回城,在回城过程中被打断就要重来
例子:我们来做一个效果,我们鼠标在盒子上移动,数字就变化 +1
基础样式代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.box {
width: 200px;
height: 200px;
background-color: red;
margin: 100px auto;
text-align: center;
line-height: 200px;
font-size: 30px;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
接下来我们来实现这个效果
没防抖时:
// 获取盒子
const box = document.querySelector(".box")
// 定义一个num控制数字
let i = 0
// 设置鼠标移动事件
box.onmousemove = function() {
// 移动就+1
box.innerHTML = i++
}
如图所示,我们鼠标移动,数字不停的+1
我们使用防抖的方式写,这里介绍2种方式
第一种 先执行
// 获取盒子
const box = document.querySelector(".box")
// 控制数字
var num = 1
// 存一个延迟器 关键
let timer //undefined
// setInterval(() => {
// console.log(typeof timer) //大家可以实验一下可以更了解原理
// }, 1000)
box.onmousemove = function () {
let obj = timer //第一次是undefined
// 移动就清除定时器
clearTimeout(timer)
// 当鼠标不在移动时执行延迟器 1s后执行
timer = setTimeout(() => {
// 给timer传一个空 空就赋值给了全局作用域种的timer
// 只有当鼠标移动时 全局作用域timer赋值给了obj
timer = null
}, 1000)
// 一移入就判断
// 第一次obj是undefined 所以一移入就 +1
// 第二次我鼠标停止不动 timer=null 就赋值给了全局的timer
// 只有移动才触发全局的timer赋值给 obj 所以 +1
if (!obj) {
// num++
box.innerHTML = num++
}
}
第二种 后执行
// 获取盒子
const box = document.querySelector(".box")
// 控制数字
var num = 1
// 存一个延迟器
let timer
box.onmousemove = function () {
// 鼠标移动就清除延迟器
clearTimeout(timer)
// 鼠标停止时 1s +1
// 继续移动停止 1s +1
// 只有移动了才会触发
timer = setTimeout(() => {
box.innerHTML = num++
}, 1000)
}
节流
节流是什么?
节流是单位时间内,频繁触发事件,只执行一次
通俗易懂点就是把防抖想象成MOBA游戏中角色的技能,在技能冷却时间内,技能无法释放,只有冷却结束才可以继续释放
使用场景:
高频事件: 鼠标移动 mousemove、页面尺寸缩放 resize 、滚动条滚动 scroll 等等
例子:与上面防抖例子一样 样式也一样 我们来使用节流处理数字
介绍二种写法
第一种 延迟器
// 获取盒子
const box = document.querySelector(".box")
// 控制数字
let num = 1
// 存延迟器
let timer
// 绑定鼠标移动事件
box.onmousemove = function () {
// 移动就判断 不移动就一直不进入判断
// 第一次移动timer 为undefined
// 第一次为undefined !undefined为true 执行
if (!timer) {
timer = setTimeout(() => {
// 1s之后 null赋值给timer 现在全局里的timer为null
timer = null
// 1s后 num++
box.innerHTML = num++
}, 1000)
}
}
第二种 时间戳
// 获取盒子
const box = document.querySelector(".box")
// 控制数字
let num = 1
// 控制时间
var timeNew = 0;
// 绑定鼠标移动事件
box.onmousemove = function () {
// 获取时间戳
let timeOld = Date.now()
// 判断如果老时间戳 - 新时间戳 大于了 1000 就执行
if (timeOld - timeNew > 1000) {
// 大于了就把老时间戳赋值给新时间戳
// 这样就可以控制住时间
timeNew = timeOld
// 大于就++
box.innerHTML = num++
}
}
感谢大家的阅读,本人文笔有限,如有不对的地方,可以向我提出,感谢大家!