admin管理员组文章数量:1530517
概念知识
防抖:事件(Event)触发时,对应的执行函数在执行等待时间内如果事件再次触发,则对应的执行函数重新开始执行,当执行等待时间结束,对应的执行函数开始执行。
- 应用场景:input事件,当用户进行输入时,oninput事件一直会被触发,如果在input事件中有执行接口请求操作,则会导致频繁的请求接口,消耗过多性能处理输入事件,可添加函数防抖操作,在规定的时间内如果输入停止或中断,再请求相应的接口,这无疑会是释放系统资源。
节流:当事件出现高并发工况时,事件对应的响应函数将会被频繁调用,大量占用系统资源,甚至可能导致系统宕机,为解决这一问题,限定单位时间内(运行周期),事件的响应函数只执行一次,到达下一周期时,如果事件再次触发,则函数可被再次调用一次。
- 应用场景:在form表单提交时,如果遇到网络问题时,用户多次点击提交发现无反馈,如果一直点击提交,则在网络恢复后,会执行大量重复操作,加入节流操作后,则单位时间内(周期内),响应函数的执行只有一次,降低重复操作的频率,提升系统性能。
防抖及节流的实现与功能导出:
//debounce文件
// 防抖函数实现
// fn: 实现防抖的函数
// delay: 延迟的时间
// immediately: 是否立即执行(首次加载执行)
// resultCallback: 函数返回值回调函数
export function debounce(fn, delay, immediately = false, resultCallback = () => {}) {
let timer = null;
let args = arguments;
let isInvoke = false;
let result = null;
let count = 0;
try {
// 入参合法判断
if (typeof fn !== 'function') throw new Error(`ERR:: ${args[0]} not a funciton`);
if (typeof delay !== 'number') throw new Error(`ERR:: ${args[1]} not a number`);
if (typeof immediately !== 'boolean') throw new Error(`ERR:: ${args[2]} not a boolean`);
if (typeof resultCallback !== 'function') throw new Error(`ERR:: ${args[3]} not a boolean`);
return function (...arg) {
// 第一次操作是否立即执行
if (immediately && !isInvoke) {
result = fn.apply(this, arg) + ` -> count >>> ${++count}`;
resultCallback(result);
isInvoke = true;
}
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
result = fn.apply(this, arg) + ` -> count >>> ${++count}`;
resultCallback(result);
isInvoke = false;
}, delay);
}
} catch (error) {
console.log(error);
}
}
// 节流函数实现
// fn: 实现防抖的函数
// delay: 延迟的时间
// immediately: 是否立即执行(首次加载执行)
// resultCallback: 函数返回值回调函数
export function throllte(fn, delay, immediately = false, resultCallback = () => {}) {
let timer = null;
let args = arguments;
let isInvoke = false;
let result = null;
let count = 0;
let status = true;
try {
// 入参合法判断
if (typeof fn !== 'function') throw new Error(`ERR:: ${args[0]} not a funciton`);
if (typeof delay !== 'number') throw new Error(`ERR:: ${args[1]} not a number`);
if (typeof immediately !== 'boolean') throw new Error(`ERR:: ${args[2]} not a boolean`);
if (typeof resultCallback !== 'function') throw new Error(`ERR:: ${args[3]} not a boolean`);
return function (...arg) {
// 第一次操作是否立即执行
if (immediately && !isInvoke) {
result = fn.apply(this, arg) + `count >>> ${++count}`;
resultCallback(result);
isInvoke = true;
}
if (status) {
status = false;
setTimeout(() => {
result = fn.apply(this, arg) + `count >>> ${++count}`;
status = true;
resultCallback(result);
isInvoke = false;
}, delay);
}
}
} catch (error) {
console.log(error);
}
}
ES-Module使用:
// main文件
import {
debounce,
throllte
}
from './debounce.js';
const item = document.querySelector("input");
const display = document.querySelector('p');
const switchMenu = document.querySelector("#switchMenu");
switchMenu.value = '';
switchMenu.onchange = () => {
switch (+switchMenu.value) {
case 1:
item.oninput = debounce(lisen, 500, false, (result) => {
display.innerText = result;
});
break;
case 2:
item.oninput = throllte(lisen, 2000, true, (result) => {
display.innerText = result;
})
break;
default:
break;
}
console.log(switchMenu.value);
}
function lisen() {
// console.log('输入监听事件');
return 'this is a demo'
}
Demo演示使用
演示HTML
<!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>
<div>这里显示操作结果:<p></p>
</div>
<select name="switchMenu" id="switchMenu">
<option value="1">防抖模式</option>
<option value="2">节流模式</option>
</select>
<input type="text">
<script type="module" src="./main.js"></script>
</body>
</html>
使用效果
本文标签: 手把手防抖JavaScript
版权声明:本文标题:手把手教学----JavaScript防抖及节流实现 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1725429503a1022739.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论