JavaScript函数防抖与函数节流的定义及使用详解
作者:EASYLZH
一、函数防抖(Debouncing)
1、基本概念
在触发事件后的规定时间内只能执行一次,如果在规定时间内又触发了该事件。则会重新开始计算规定时间;
2、算法思想
(1)首先定义一个函数,函数进入页面立即执行一次,且永远执行最新的一次;
(2)返回一个匿名函数;
(3)在匿名函数里使用计时器setTimeout设置规定时间;
(4)在使用clearTimeout来清除上一次的函数调用;
(5)在事件中调用该函数;
(6)必须返回函数,因为事件只能调用函数;
3、代码实现
//功能:防抖函数 function debounce(callback,time = 300){ let t; //返回一个匿名函数 return function(){ clearTimeout(t);//清除定时器 t = setTimeout(callback,time);//设置定时器 } } //在onscroll事件中调用防抖函数 window.onscroll = debounce(function(){ console.log("调用了1次"); },500);
onscroll事件为滚动条事件 属于window对象
callback为回调函数
4、使用场景
防抖函数就是为了防止用户进行一些频繁的点击事件、输入文字或者滚动事件时,对应绑定的事件发生多次的场景,这些事件的触发频率很高,不做限制的话可能一秒执行几十次甚至几百次,会造成不必要的浪费。
下面用一个在网页中经常遇到的回到顶部案例说明
代码:
<!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>Document</title> </head> <style> *{ margin: 0; padding: 0; } body{ height: 5000px; background-color: aqua; } img{ position: fixed; bottom: 100px; right: 50px; display: none; } </style> <body> <img id="returntop" src="./img/return.png" alt=""> </body> <script> //函数防抖 function delbounce(callback,time = 300){ let t; return function(){ clearTimeout(t); t = setTimeout(callback,time); } } //绑定滚动条事件 window.onscroll = delbounce(returntop,200); //onscroll 滚动条事件 属于window事件 不写到标签里 function returntop(){ //距离浏览器顶部的距离 console.log("调用了1次"); let num = document.body.scrollTop || document.documentElement.scrollTop; // console.log(parseInt(num)); //判断隐藏和出现 if(parseInt(num) > 400){ document.getElementById("returntop").style = "display:block"; }else{ document.getElementById("returntop").style = "display:none"; } } </script> </html>
效果:
分析:大大减少了函数的调用次数,减少了对计算机资源的浪费等等;
二、函数节流(Throlle)
1、基本概念
函数节流和函数防抖恰好相反,规定在一个单位时间内,只能调用一次函数,如果在这个规定时间内对此调用函数,只能有一次被调用,相当于子啊这个规定时间内永远只会执行第一次。
2、算法思想
(1)获取刚进入页面的时间戳;
(2)获取事件开始发生的时间戳;
(3)如果相隔的时间大于设定的时间,则继续下一次调用;
(4)更新上一次调用的时间,永远执行第一次;
3、代码实现
//功能:函数节流 永远执行第一次 function throlle(callback,time){ let lasttime = new Date().getTime();//获取刚进入页面时的时间戳 return function(){ let nowtime = new Date().getTime();//获取滚动条开始滑动的时间戳 if (nowtime - lasttime > time){//如果时间间隔大于设定的时间 则继续下一次调用 callback(); lasttime = nowtime;//更新上一次的时间戳 } } } window.onscroll = throlle(function(){ console.log("调用了1次"); },500);
getTime():用来获取当前的时间戳
4、使用场景
函数节流可以运用于所有的数据请求、按钮和下拉刷新等等。
用一个登录按钮的使用的案例来说明
代码:
<!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>Document</title> </head> <style> *{ margin: 0; padding: 0; } body{ background: url(./img/login.gif) no-repeat; background-size: 100%; } div.login{ width: 500px; height: 360px; background-color: rgba(0, 0, 0, 0.2); border-radius: 10px; margin: 50px auto; } div.login h1{ padding-top: 10px; padding-bottom: 10px; text-align: center; color: white; } div.email,div.tel,div.pwd{ margin-left: 17px; } div.login div.email input,div.login div.tel input,div.login div.pwd input{ width: 450px; height: 45px; padding-left: 11px; margin: 8px 0; } div.login div.btn button{ width: 450px; height: 40px; color: white; background-color: rgba(0, 0, 0, 0.2); border-radius: 20px; text-align: center; margin-top: 10px; margin-left: 20px; line-height: 40px; border: 0; } div.login div.btn button:hover{ cursor: pointer; background-color:rgba(0, 0, 0, 0.4) ; } div.login #emailarr,#telarr,#pwdarr{ color: red; font-size: 12px; } </style> <body> <div class="login"> <h1>后台管理系统</h1> <div class="email"> <input type="email" id="email" onblur="isEamil()" placeholder="请输入邮箱..." required><br> <div id="emailarr"></div> </div> <div class="tel"> <input type="tel" pattern="^1([358][0-9]|4[456789]|66|7[0135678]|9[189])\d{8}$" id="tel" onblur="isTel()" placeholder="请输入电话号码..." required><br> <div id="telarr"></div> </div> <div class="pwd"> <input type="password" pattern="^[0-9a-zA-Z]{6,12}" onblur="isPwd()" id="pwd" placeholder="请输入密码..." required><br> <div id="pwdarr"></div> </div> <div class="btn"> <button id="btn" disabled>登录</button> </div> </div> </body> <script> //功能:表单验证 let emailState = false; let telState = false; let pwdState = false; //验证邮箱格式是否正确 function isEamil(){ let email = document.getElementById("email"); if(email.validity.valueMissing){ email.style = "border:2px red solid"; document.getElementById("emailarr").innerHTML = "* 邮箱不能为空!"; emailState = false; isState(); return false; } if(email.validity.typeMismatch){ email.style = "border:2px red solid"; document.getElementById("emailarr").innerHTML = "* 请输入正确的邮箱!"; emailState = false; isState(); return false; } email.style = "border:2px green solid"; document.getElementById("emailarr").innerHTML = ""; emailState = true; isState() return true; } //验证电话号码格式是否正确 function isTel(){ let tel = document.getElementById("tel"); if(tel.validity.valueMissing){ email.style = "border:2px red solid"; document.getElementById("telarr").innerHTML = "* 电话号码不能为空!"; telState = false; isState(); return false; } if(tel.validity.patternMismatch){ tel.style = "border:2px red solid"; document.getElementById("telarr").innerHTML = "* 请输入正确的电话号码!"; telState = false; isState(); return false; } tel.style = "border:2px green solid"; document.getElementById("telarr").innerHTML = ""; telState = true; isState() return true; } //验证密码格式是否正确 function isPwd(){ let pwd = document.getElementById("pwd"); if(pwd.validity.valueMissing){ pwd.style = "border:2px red solid"; document.getElementById("pwdarr").innerHTML = "* 密码不能为空!"; pwdState = false; isState(); return false; } if(pwd.validity.patternMismatch){ pwd.style = "border:2px red solid"; document.getElementById("pwdarr").innerHTML = "* 请输入正确的密码!"; pwdState = false; isState(); return false; } pwd.style = "border:2px green solid"; document.getElementById("pwdarr").innerHTML = ""; pwdState = true; isState() return true; } //判断三个结果是否都为true removeAttribute() 删除获取的的某个节点的对应属性 function isState(){ if(emailState && telState && pwdState){ document.getElementById("btn").removeAttribute("disabled"); }else{ document.getElementById("btn").setAttribute("disabled","disabled");//设置属性 } } //登陆成功 function login(){ console.log("函数调用1次"); //将数据发给后台处理 //后台返回两种结果 error success //将成功后的用户信息进行本地存储 userid token // let userid = 123456; // localStorage.setItem("userid",userid); // location.href = "./logininfo.html"; } document.getElementById("btn").onclick = throlle(login,5000); function throlle(callback,time){ let lasttime = new Date().getTime(); return function(){ let nowtime = new Date().getTime(); if (nowtime - lasttime > time){//在time时间段 不能在调用函数 callback(); lasttime = nowtime; } } } </script> </html>
效果:
分析:在规定时间不允许在点击登录按钮 超过规定时间以后才能继续点击,进行下一次登录;
到此这篇关于JavaScript函数防抖与函数节流的定义及使用详解的文章就介绍到这了,更多相关JavaScript函数防抖 节流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!