防抖点击指令
# 题目
- 确保在一定时间内当快速点击按钮多次时只触发一次点击事件
- 你需要支持防抖延迟时间选项, 用法如
v-debounce-click:ms
<script setup>
const VDebounceClick = {};
function onClick() {
console.log("Only triggered once when clicked many times quicky");
}
</script>
<template>
<button v-debounce-click:200="onClick">Click on it many times quickly</button>
</template>
# 题目分析
使用v-debounce-click
指令,该指令可以延迟执行一个点击事件,在一定时间内多次点击只会触发一次。考察的是对自定义指令的申明和使用,已经对防抖节流的理解。
# 实现
<script setup>
function debounce(fn, delay) {
let t = null;
return function () {
if (t) clearTimeout(t);
t = setTimeout(fn, delay);
};
}
const VDebounceClick = {
mounted: (el, binding) => {
let clickfn = debounce(binding.value, binding.arg);
el.addEventListener("click", clickfn);
},
};
function onClick() {
console.log("Only triggered once when clicked many times quickly");
}
</script>
<template>
<div>
<button v-debounce-click:200="onClick">
Click on it many times quickly
</button>
</div>
</template>
# 解析
在 切换焦点指令
章节详细说明了自定义指令的实现和使用,这里通过 binding.value 获取到点击事件,binding.arg 获取到延迟时间,通过 debounce 函数实现防抖功能。与防抖相对应的还有节流。
- 防抖(debounce)
原理:当持续触发事件时,在设定的时间内没有再次触发事件,则事件才会处理函数一次;如果在设定时间之前再次触发该事件,则重新开启定时器,执行最后一次触发事件
应用场景:
- scroll 事件滚动
- 浏览器窗口的缩放 resize 事件
- 搜索框输入查询
- 表单验证
- 按钮提交
节流(throttle)
原理:在持续触发事件时,在一定时间内只调用一次事件函数,如果在设定时间内再次触发事件,则不执行,目的就是减少一段时间内的触发频率
应用场景:
- dom 元素拖拽功能实现
- 计算鼠标移动距离
- 监听 scroll 事件滚动
- 搜索提交功能按钮
window.onscroll = throttle(function () {
console.log("滚动");
}, 500);
function throttle(fn, delay) {
let flag = true;
return function () {
if (flag) {
setTimeout(() => {
fn.call(this);
flag = true;
}, delay);
}
flag = false;
};
}