资讯详情

JavaScript 防抖和节流

📅 2026/10/13 9:13:40 | 华诺云谱 👁 阅读
JavaScript 防抖和节流
文章目录JavaScript 防抖和节流防抖Debounce概念代码实现完整代码节流Throttle概念代码实现完整代码对比按钮防止频繁点击JavaScript 防抖和节流防抖Debounce概念核心思想停止触发后延迟执行。如果在等待期间又触发事件就重新计时。类比等电梯如果有人进来了电梯就重新计时关门知道没有人再进才关门运行。场景搜索框实时联想输入完后才发送请求表单输入校验输入完后才校验窗口 resize 结束后重新布局按钮重复点击防护代码实现初始代码functiondebounce(fn,delay){lettimernullreturnfunction(...args){if(timer)clearTimeout(timer)timersetTimeout((){fn.apply(this,args)},delay)}}增加立即执行功能functiondebounce(fn,delay,immediate){lettimernullletisDebouncedfalse// 是否防抖模式returnfunction(...args){if(timer)clearTimeout(timer)if(immediate!isDebounced){fn.apply(this,args)// 立即执行后进入防抖模式isDebouncedtrue}else{timersetTimeout((){fn.apply(this,args)// 防抖模式结束下次输入内容立即执行isDebouncedfalse},delay)}}}增加取消功能functiondebounce(fn,delay,immediate){lettimernullletisDebouncefalse// 是否进入防抖模式const_debouncefunction(...args){if(timer)clearTimeout(timer)if(immediate!isDebounce){fn.apply(this,args)// 立即执行后进入防抖模式isDebouncetrue}else{timersetTimeout((){fn.apply(this,args)// 防抖模式结束下次输入内容立即执行isDebouncefalse},delay)}}_debounce.cancelfunction(){if(timer)clearTimeout(timer)timernullisDebouncefalse}return_debounce}完整代码!DOCTYPEhtmlhtmllangenheadmetacharsetUTF-8title防抖/title/headbodyinputidsearchInputtypetextplaceholder请输入dividsearchResult/divbuttonidbtnCancel取消/buttonscriptfunctiondebounce(fn,delay,immediate){lettimernullletisDebouncefalse// 是否进入防抖模式const_debouncefunction(...args){if(timer)clearTimeout(timer)if(immediate!isDebounce){fn.apply(this,args)// 立即执行后进入防抖模式isDebouncetrue}else{timersetTimeout((){fn.apply(this,args)// 防抖模式结束下次输入内容立即执行isDebouncefalse},delay)}}_debounce.cancelfunction(){if(timer)clearTimeout(timer)timernullisDebouncefalse}return_debounce}constsearchInputdocument.querySelector(#searchInput)constsearchResultdocument.querySelector(#searchResult)constbtnCanceldocument.querySelector(#btnCancel)constdebounceFndebounce((e){searchResult.innerHTMLe.target.value.trim()},1000,true)searchInput.addEventListener(input,debounceFn)btnCancel.addEventListener(click,(){debounceFn.cancel()})/script/body/html节流Throttle概念核心思想每隔固定时间执行一次。不管你触发多频繁都按固定频率执行。类比水龙头拧开水龙头后水固定流速流出不会英文你一直拧就无限加速。场景滚动事件鼠标移动输入框实时字数统计游戏中的按键连续响应代码实现初始代码functionthrottle(fn,interval){letlastTime0returnfunction(...args){constnowTimenewDate().getTime()if(nowTime-lastTimeinterval){fn.apply(fn,args)lastTimenowTime}}}控制立即执行和最后一次执行功能节流函数默认会立即执行可以通过 leading 变量控制是否立即执行。functionthrottle(fn,interval500,leadingfalse,trailingtrue){letlastTime0lettimernullreturnfunction(...args){letnowTimeDate.now()// 首次不立即执行// !lastTime表示第一次执行if(!lastTime!leading){lastTimenowTime}// 计算等待时间0时执行函数constwaitTimeinterval-(nowTime-lastTime)// 执行节流函数if(waitTime0){if(timer){clearTimeout(timer)timernull}fn.apply(this,args)lastTimenowTimereturn}// 执行最后一次if(trailing!timer){timersetTimeout((){fn.apply(this,args)lastTimenowTime timernull},waitTime)}}}增加取消功能functionthrottle(fn,interval500,leadingfalse,trailingtrue){letlastTime0lettimernullconst_throttlefunction(...args){letnowTimeDate.now()// 首次不立即执行// !lastTime表示第一次执行if(!lastTime!leading){lastTimenowTime}// 计算等待时间0时执行函数constwaitTimeinterval-(nowTime-lastTime)// 执行节流函数if(waitTime0){if(timer){clearTimeout(timer)timernull}fn.apply(this,args)lastTimenowTimereturn}// 执行最后一次if(trailing!timer){timersetTimeout((){fn.apply(this,args)lastTimenowTime timernull},waitTime)}}_throttle.cancelfunction(){if(timer)clearTimeout(timer)timernulllastTime0}return_throttle}完整代码!DOCTYPEhtmlhtmllangenheadmetacharsetUTF-8title节流/title/headbodytextareaidsearchInputcols30rows10placeholder请输入/textareadividsearchResult/divbuttonidbtnCancel取消/buttonscriptfunctionthrottle(fn,interval500,leadingfalse,trailingtrue){letlastTime0lettimernullconst_throttlefunction(...args){letnowTimeDate.now()// 首次不立即执行// !lastTime表示第一次执行if(!lastTime!leading){lastTimenowTime}// 计算等待时间0时执行函数constwaitTimeinterval-(nowTime-lastTime)// 执行节流函数if(waitTime0){if(timer){clearTimeout(timer)timernull}fn.apply(this,args)lastTimenowTimereturn}// 执行最后一次if(trailing!timer){timersetTimeout((){fn.apply(this,args)lastTimenowTime timernull},waitTime)}}_throttle.cancelfunction(){if(timer)clearTimeout(timer)timernulllastTime0}return_throttle}constsearchInputdocument.querySelector(#searchInput)constsearchResultdocument.querySelector(#searchResult)constbtnCanceldocument.querySelector(#btnCancel)constthrottleFnthrottle((e){searchResult.innerHTML共计e.target.value.trim().length字},2000)searchInput.addEventListener(input,throttleFn)btnCancel.addEventListener(click,(){throttleFn.cancel()})/script/body/html对比按钮防止频繁点击按钮防频繁点击既不是常规防抖也不是常规节流而是「立即执行 冷却锁定」。如果非要在两者里选优先选节流的 “立即执行版”leading-edge但实际项目里更常见的做法是直接用按钮disabled状态 一个锁标志。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑