什么是防抖和节流? 防抖:通过setTimeout的方式,在一定的时间间隔内,将多次触发变成一次触发
节流:减少一段时间的触发频率
为什么要使用防抖和节流? 在实际开发过程中,前端的按钮交互等操作往往是和后端接口数据库紧密联系的
如果不对用户的交互操作加以限制,例如用户极其频繁地服务器发起请求,点击按钮,可能会影响到后端接口及服务器的正常运行或者造成页面卡顿等现象,使用防抖和节流就显得尤为重要了。
防抖 明确需求:在用户第一次点击之后的一段时间内,如果用户频繁点击,则不处理这个事件
很容易想到用定时器来处理,如果持续触发则清除这个定时器,这也运用到了闭包的思想
扩展:为了良好的用户体验,也可以设置在第一次点击时立即发送请求,而不是延时发送
实例 用一条输入框,以及一个按钮来模拟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!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 > 防抖</title > </head > <body > <input type ="text" > <input type ="submit" id ="btn" value ="点击" > <script > let btn = document .querySelector("#btn" ); btn.addEventListener("click" ,debounce(submit,1000 ,true )); function submit ( ) { console .log(1 ); } function debounce (fn,timer,trigger ) { let t = null ; return function ( ) { if(t){ clearTimeout (t); } if (trigger){ let firstClick = !t; if(firstClick){ fn.apply(this ,arguments ); } t = setTimeout (()=> { t = null ; },timer) }else { t = setTimeout (()=> { fn.apply(this ,arguments ); },timer) } } } </script > </body > </html >
一些注意点:
节流 节流需要控制执行的频率而不管用户的操作,你点得再快,我也只隔一段事件后再操作,有时间戳版本和定时器版本
时间戳版本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <!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 > </title > </head > <body > <input type ="text" > <input type ="button" value ="点击" id ="btn" > <script > let btn = document .querySelector('#btn' ); btn.addEventListener("click" , throttle(submit, 2000 )); function submit ( ) { console .log(1 ); } function throttle (fn,delay ) { let begin = 0 ; return function ( ) { let cur = new Date ().getTime(); if(cur-begin>delay){ fn.apply(this ,arguments ); begin = cur; } } }
定时器版本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <!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 > </title > </head > <body > <input type ="text" > <input type ="button" value ="点击" id ="btn" > <script > let btn = document .querySelector('#btn' ); btn.addEventListener("click" , throttle(submit, 2000 )); function submit ( ) { console .log(1 ); } function throttle (fn,delay ) { let run = true ; return function ( ) { if(!run){ return ; } run = false ; setTimeout (()=> { fn.apply(this ,arguments ); run = true ; },delay) } }