学习前提
理解input事件、setTimeout、闭包和数组筛选。
本课完成后你能做什么
减少连续输入触发的重复工作,并区分防抖与请求取消。
先理解机制
防抖每次清除旧计时器,只有输入暂停达到阈值后才执行;节流则限制一段时间内的执行频率。搜索适合等待用户稍作停顿,拖动反馈往往需要持续更新,两者不可机械替换。
把字符串值传给延迟函数,而不是长时间依赖事件对象或稍后读取不确定的DOM状态。中文输入法组合过程中不应对每个中间拼音查询;isComposing与compositionend帮助在确认输入后更新。
本例在本地数组筛选,防抖主要用于教学。若换成网络请求,清除计时器只能取消尚未发起的工作,无法撤回已发出的请求;仍需取消旧请求并防止过期结果写回。
可运行示例
<label for="query">Find a course</label><input id="query" type="search">
<p id="result" role="status"></p>
<script>
const courses = ['HTML semantics', 'CSS Grid', 'JavaScript promises'];
const input = document.querySelector('#query');
const result = document.querySelector('#result');
function debounce(fn, delay) {
let timer;
return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); };
}
const update = debounce(query => {
const found = courses.filter(title => title.toLowerCase().includes(query.trim().toLowerCase()));
result.textContent = found.length ? found.join(' · ') : 'No matching courses';
}, 250);
input.addEventListener('input', event => { if (!event.isComposing) update(input.value); });
input.addEventListener('compositionend', () => update(input.value));
update('');
</script>
推演与验证
快速输入css,暂停后只显示CSS Grid。删除查询恢复全部,输入不存在的词显示空结果。用中文输入法观察候选阶段不会反复刷新;在控制台给update内部加计数可比较有无防抖的调用次数。
常见错误与边界
250毫秒不是通用标准,应依据交互和反馈调整。对立即必要的验证或保存操作盲目防抖,可能让用户离开页面时丢失最后一次工作。
动手练习
增加“立即搜索”按钮,使按钮取消等待并立即处理最新查询,避免稍后重复执行。
参考解法与理由
把实际筛选提取为search函数,防抖包装器暴露cancel方法;按钮先cancel再调用search(input.value)。不要在按钮上再调用延迟包装器。