JS防抖节流函数的实现与使⽤场景
⽬录
⼀、什么是函数防抖
1、为什么需要函数防抖?
2、函数防抖的要点
3、函数防抖的实现
4、函数防抖的使⽤场景
⼆、什么是函数节流
1、函数节流的要点
2、函数节流的实现
3、函数节流的使⽤场景
总结
⼀、什么是函数防抖
概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执⾏⼀次,如果触发事件后在 n 秒内⼜触发了事件,则会重新计算函数延执⾏时间。
1、为什么需要函数防抖?
前端开发过程中,有⼀些事件,常见的例如,onresize,scroll,mousemove ,mousehover 等,会被频繁触发(短时间内多次触发),不做限制的话,有可能⼀秒之内执⾏⼏⼗次、⼏百次,如果在这些函数内部执⾏了其他函数,尤其是执⾏了操作 DOM 的函数(浏览器操作 DOM 是很耗费性能的),那不仅会浪费计算机资源,还会降低程序运⾏速度,甚⾄造成浏览器卡死、崩溃。
2、函数防抖的要点
函数防抖的要点,是需要⼀个 setTimeout 来辅助实现,延迟运⾏需要执⾏的代码。如果⽅法多次触发,则把上次记录的延迟执⾏代码⽤ clearTimeout 清掉,重新开始计时。若计时期间事件没有被重新触发,等延迟时间计时完毕,则执⾏⽬标代码。
3、函数防抖的实现
//HTML部分
<div>
账户:<input type="text" id="myinput">
</div>
//JS部分
function debounce(fun,wait=1500){//ES6语法 wait=1500 设置参数默认值,如果没有输⼊wait就会使⽤1500
let timeout = null
return function(){
if(timeout){//如果存在定时器就清空
clearTimeout(timeout)
}
timeout=setTimeout(function(){
fun()
},wait)
}
}
function testUname(){
console.log("输⼊结束!")
}
上⾯的代码就是防抖函数的简单运⽤,只要你每次输⼊间隔⼤于⼀秒,那么永远不会打“印输⼊结束!”,直到你停⽌输⼊吗,这是因为每⼀次的输⼊都会清除上⼀次的计时器。
看到这⾥你以为就结束了吗?别急,让我们继续看:
//HTML部分
<div>
账户:<input type="text" id="myinput">
</div>
//JS部分
function debounce(fun,wait=1500){
let timeout = null
return function(){
console.log(this)//<input id="myinput" type="text">
console.log(arguments)//Arguments { 0: input, … }
if(timeout){//如果存在定时器就清空
clearTimeout(timeout)
}
timeout=setTimeout(function(){
console.log(this)//Window
console.log(arguments)//Arguments { … }
fun()
},wait)
}
}
function testUname(){
console.log("输⼊结束!")
}
⽆论是防抖还是节流,我们都要解决两个问题,this指向和arguments。
如果没有特殊指向,setInterval和setTimeout的回调函数中this的指向都是window。这是因为JS的定时器⽅法是定义在window下的。这显然不是我们希望的,因为我们监听的是input输⼊框,所以我们希望定时器⾥⾯的this指向input。
那么有什么⽅法可以改变this指向吗?
⼀种简单的办法就是我们可以⽤参数把定时器外层函数的this和arguments保存下来。然后再通过apply改变定时器要执⾏的函数fun的指向。
//JS部分
function debounce(fun,wait=1500){
let timeout = null
return function(){
let _this = this
let arg = arguments
if(timeout){//如果存在定时器就清空
clearTimeout(timeout)
}
timeout=setTimeout(function(){
console.log(_this)//<input id="myinput" type="text">
console.log(arg)//Arguments { 0: input, … }
fun.apply(_this,arg)
},wait)
}
}
当然,你也可以⽤ES6的箭头函数新特性:箭头函数的 this 始终指向函数定义时的 this,⽽⾮执⾏时。箭头函数需要记着这句话:“箭头函数中没有 this 绑定,必须通过查作⽤域链来决定其值,如果箭头函数被⾮箭头函数包含,则 this 绑定的是最近⼀层⾮箭头函数的 this,否则,this 为 undefined”。
所以也可以这样写:
js arguments//JS部分
function debounce(fun,wait=1500){
let timeout = null
return function(){
if(timeout){//如果存在定时器就清空
clearTimeout(timeout)
}
timeout=setTimeout(()=>{
console.log(this)//<input id="myinput" type="text">
console.log(arguments)//Arguments { 0: input, … }
fun.apply(this,arguments)
},wait)
}
}
4、函数防抖的使⽤场景
函数防抖⼀般⽤在什么情况之下呢?⼀般⽤在,连续的事件只需触发⼀次回调的场合。具体有:
搜索框搜索输⼊。只需⽤户最后⼀次输⼊完,再发送请求;
⽤户名、⼿机号、邮箱输⼊验证;
浏览器窗⼝⼤⼩改变后,只需窗⼝调整完后,再执⾏ resize 事件中的代码,防⽌重复渲染。
⼆、什么是函数节流
概念:限制⼀个函数在⼀定时间内只能执⾏⼀次。
举个栗⼦,坐⽕车或地铁,过安检的时候,在⼀定时间(例如10秒)内,只允许⼀个乘客通过安检⼊⼝,以配合安检
⼈员完成安检⼯作。上例中,每10秒内,仅允许⼀位乘客通过,分析可知,“函数节流”的要点在于,在⼀定时间之
内,限制⼀个动作只执⾏⼀次。
1、函数节流的要点
主要实现思路就是通过 setTimeout 定时器,通过设置延时时间,在第⼀次调⽤时,创建定时器,先设
定⼀个变量,然后把定时器赋值给这个变量,再写⼊需要执⾏的函数。第⼆次执⾏这个函数时,会判断变量是否true,是则返回。当第⼀次的定时器执⾏完函数最后会设定变量为false。那么下次判断变量时则为false,函数会依次运⾏。⽬的在于在⼀定的时间内,保证多次函数的请求只执⾏最后⼀次调⽤。
这么看是不是有点看不懂?让我们来看代码:
2、函数节流的实现
//JS部分
function debounce(fun,wait=1000){//定时器⽅案
let timer = null;//先设定⼀个变量
return function(){
if(!timer){//如果timer为null就进⼊
timer = setTimeout(function(){//然后把定时器赋值给这个变量
fun()//再写⼊需要执⾏的函数
timer = null//第⼀次的定时器执⾏完函数最后会设定变量为false,这⾥的 timer = null有两个作⽤,1、开启下⼀次的⼊⼝,2、清除后⾯的定时器 })
}
}
}
function testUname(){
console.log(Math.random())
}
同样的,节流函数也要解决this和arguments的问题,改进后如下:
//箭头函数写法
function debounce(fun,wait=1000){
let timer = null
return function(){
if(!timer){
timer = setTimeout(()=>{
fun.apply(this,arguments)
timer = null
},wait)
}
}
}
/
/参数保存法
function debounce(fun,wait=1000){
let timer = null
return function(){
let _this = this
let arg = arguments
if(!timer){
timer = setTimeout(function(){
fun.apply(_this,arg)
timer = null
},wait)
}
}
}
3、函数节流的使⽤场景
到此为⽌,相信各位应该对函数节流有了⼀个⽐较详细的了解,那函数节流⼀般⽤在什么情况之下呢?
懒加载、滚动加载、加载更多或监听滚动条位置;
百度搜索框,搜索联想功能;
防⽌⾼频点击提交,防⽌表单重复提交;
总结
到此这篇关于JS防抖节流函数的实现与使⽤场景的⽂章就介绍到这了,更多相关JS防抖节流函数内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论