在日常工作当中总会遇到一些时间连续触发(比如搜索查询,用户输入搜索过程中不断调用后端api查询数据、widow触发resize或滚动时间等),这个时候为了不浪费资源、优化性能我们常常采用防抖/节流的方法来处理
防抖定义:函数执行过一次后,在等待某时间段内不能再次执行,在等待时间内触发此函数,则重新计算等待时间。
节流定义:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
在平时的工作中一定都有遇到过这种情况,点击了一次按钮之后事件还没有处理完按钮又被点击了,正常情况下肯定是要避免这种情况的,这时候在代码中我会这样写(使用定时器代替接口)。
<button onclick="submit(event,1000)">点击</button> <script> // function submit(e) {
// setTimeout(() => {
// console.log(1);
// }, 1000)
// }
function submit(e, delay) {
e.target.disabled = true;
setTimeout(() => {
console.log(1);
e.target.disabled = false;
}, delay)
}
</script> 除了点击事件,滚动事件也是非常要注意的,每次滚动条滚动到底部的时候都会去请求数据,为了避免来回滚动造成连续发送多次请求的情况,上面的方法肯定是不适用的,看代码
<script>
function debounce(fn, delay) {
var timer = null;
return function () {
if (timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(fn, delay);
}
}
function handle() {
console.log('A');
}
window.addEventListener("scroll", debounce(handle, 1000));
</script>
在操作停止1秒钟后才会去请求接口。
补充:
点击事件的这种写法非常有局限性,因为只能在button标签或者input标签中才能使用,如果事件并不是绑定在button标签或者input标签上的怎么办?(不建议这么做,按钮尽量使用button标签)
<div onclick="inner()">点击</div> <script>
function throttle(fn, delay) {
let valid = true;
return function () {
if (!valid) {
return false;
}
fn();
valid = false;
setTimeout(() => {
valid = true;
}, delay)
}
}
function show() {
console.log(1);
}
var inner = throttle(show, 1500);
</script>
|
|