JavaScript函数防抖 节流
EASYLZH 人气:0一、函数防抖(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>
效果:
分析:在规定时间不允许在点击登录按钮 超过规定时间以后才能继续点击,进行下一次登录;
加载全部内容