前言
防抖
- 防抖和节流是一种性能优化手段,将频繁调用函数进行包装处理,防止频繁处理事件,导致性能损耗,例如接收到事件后更新localStorage
目的
- 单位时间内,频繁触发事件,只执行最后一次(只要用户没有停下来,就不会执行,等到用户停下来了,最后才会执行)
应用场景
- 输入框自动搜索
- 按钮防暴击(频繁点击)
- 手机号、邮箱等表单的输入延迟校验
封装函数
function debounce(callback, timeout) {
let timerId;
return function (...args) {
// 此时的this,是DOM元素
const that = this;
// 清除上次的延时器,并再次开启延时器
clearTimeout(timerId);
timerId = setTimeout(() => {
// 调用回调函数,并重新设置this为DOM元素,再把方法参数回传
if (callback) {
callback.apply(that, args);
}
}, timeout);
};
}
使用案例
<!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>防抖函数实现</title>
<style>
.box {
width: 500px;
height: 500px;
background-color: #ccc;
color: #fff;
text-align: center;
font-size: 100px;
}
</style>
</head>
<body>
<input type="text">
<div class="box">0</div>
<script>
const input = document.querySelector('input');
const box = document.querySelector('.box');
// 延时自动搜索
const handleInput = function (e) {
console.log('发送搜索商品请求...');
}
input.addEventListener('input', debounce(handleInput, 1000));
</script>
</body>
</html>
节流
目的
- 单位时间内,频繁触发事件,按照固定频率执行(单位时间内,不能执行太多次,但一定会执行)
应用场景
- 鼠标移动事件、页面尺寸改变事件、滚动条滚动事件、音频、视频的进度变化事件
封装函数
function throttle(callback, timeout) {
// 延时器Id
let timerId;
return function (...args) {
// 如果定时器正在运行,那么拦截调用
if (!timerId) {
// 调用回调函数,并设置this和方法参数
callback.apply(this, args);
// 开启延时器,时间到时,重置定时器Id变量
timerId = setTimeout(() => {
timerId = undefined;
}, timeout);
}
}
}
使用案例
<!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>利用节流实现性能优化</title>
<style>
.box {
width: 500px;
height: 500px;
background-color: #ccc;
color: #fff;
text-align: center;
font-size: 100px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
const box = document.querySelector('.box');
// 节流,3秒内只能执行一次,下一次3秒才能执行下一次
// 正常业务逻辑
const fn = function (e) {
box.innerText++;
}
// 鼠标移动事件
box.addEventListener('mousemove', throttle(fn, 3000));
</script>
</body>
</html>
网友评论