JavaScript函數(shù)防抖與函數(shù)節(jié)流的定義及使用詳解
一、函數(shù)防抖(Debouncing)
1、基本概念
在觸發(fā)事件后的規(guī)定時間內(nèi)只能執(zhí)行一次,如果在規(guī)定時間內(nèi)又觸發(fā)了該事件。則會重新開始計算規(guī)定時間;
2、算法思想
(1)首先定義一個函數(shù),函數(shù)進入頁面立即執(zhí)行一次,且永遠執(zhí)行最新的一次;
(2)返回一個匿名函數(shù);
(3)在匿名函數(shù)里使用計時器setTimeout設(shè)置規(guī)定時間;
(4)在使用clearTimeout來清除上一次的函數(shù)調(diào)用;
(5)在事件中調(diào)用該函數(shù);
(6)必須返回函數(shù),因為事件只能調(diào)用函數(shù);
3、代碼實現(xiàn)
//功能:防抖函數(shù) function debounce(callback,time = 300){ let t; //返回一個匿名函數(shù) return function(){ clearTimeout(t);//清除定時器 t = setTimeout(callback,time);//設(shè)置定時器 } } //在onscroll事件中調(diào)用防抖函數(shù) window.onscroll = debounce(function(){ console.log("調(diào)用了1次"); },500);
onscroll事件為滾動條事件 屬于window對象
callback為回調(diào)函數(shù)
4、使用場景
防抖函數(shù)就是為了防止用戶進行一些頻繁的點擊事件、輸入文字或者滾動事件時,對應(yīng)綁定的事件發(fā)生多次的場景,這些事件的觸發(fā)頻率很高,不做限制的話可能一秒執(zhí)行幾十次甚至幾百次,會造成不必要的浪費。
下面用一個在網(wǎng)頁中經(jīng)常遇到的回到頂部案例說明
代碼:
<!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> //函數(shù)防抖 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("調(diào)用了1次"); let num = document.body.scrollTop || document.documentElement.scrollTop; // console.log(parseInt(num)); //判斷隱藏和出現(xiàn) if(parseInt(num) > 400){ document.getElementById("returntop").style = "display:block"; }else{ document.getElementById("returntop").style = "display:none"; } } </script> </html>
效果:
分析:大大減少了函數(shù)的調(diào)用次數(shù),減少了對計算機資源的浪費等等;
二、函數(shù)節(jié)流(Throlle)
1、基本概念
函數(shù)節(jié)流和函數(shù)防抖恰好相反,規(guī)定在一個單位時間內(nèi),只能調(diào)用一次函數(shù),如果在這個規(guī)定時間內(nèi)對此調(diào)用函數(shù),只能有一次被調(diào)用,相當于子啊這個規(guī)定時間內(nèi)永遠只會執(zhí)行第一次。
2、算法思想
(1)獲取剛進入頁面的時間戳;
(2)獲取事件開始發(fā)生的時間戳;
(3)如果相隔的時間大于設(shè)定的時間,則繼續(xù)下一次調(diào)用;
(4)更新上一次調(diào)用的時間,永遠執(zhí)行第一次;
3、代碼實現(xiàn)
//功能:函數(shù)節(jié)流 永遠執(zhí)行第一次 function throlle(callback,time){ let lasttime = new Date().getTime();//獲取剛進入頁面時的時間戳 return function(){ let nowtime = new Date().getTime();//獲取滾動條開始滑動的時間戳 if (nowtime - lasttime > time){//如果時間間隔大于設(shè)定的時間 則繼續(xù)下一次調(diào)用 callback(); lasttime = nowtime;//更新上一次的時間戳 } } } window.onscroll = throlle(function(){ console.log("調(diào)用了1次"); },500);
getTime():用來獲取當前的時間戳
4、使用場景
函數(shù)節(jié)流可以運用于所有的數(shù)據(jù)請求、按鈕和下拉刷新等等。
用一個登錄按鈕的使用的案例來說明
代碼:
<!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>后臺管理系統(tǒng)</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; } //判斷三個結(jié)果是否都為true removeAttribute() 刪除獲取的的某個節(jié)點的對應(yīng)屬性 function isState(){ if(emailState && telState && pwdState){ document.getElementById("btn").removeAttribute("disabled"); }else{ document.getElementById("btn").setAttribute("disabled","disabled");//設(shè)置屬性 } } //登陸成功 function login(){ console.log("函數(shù)調(diào)用1次"); //將數(shù)據(jù)發(fā)給后臺處理 //后臺返回兩種結(jié)果 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時間段 不能在調(diào)用函數(shù) callback(); lasttime = nowtime; } } } </script> </html>
效果:
分析:在規(guī)定時間不允許在點擊登錄按鈕 超過規(guī)定時間以后才能繼續(xù)點擊,進行下一次登錄;
到此這篇關(guān)于JavaScript函數(shù)防抖與函數(shù)節(jié)流的定義及使用詳解的文章就介紹到這了,更多相關(guān)JavaScript函數(shù)防抖 節(jié)流內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
常用Javascript函數(shù)與原型功能收藏(必看篇)
下面小編就為大家?guī)硪黄S肑avascript函數(shù)與原型功能收藏(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10ajaxfileupload.js實現(xiàn)上傳文件功能
這篇文章主要為大家詳細介紹了ajaxfileupload.js實現(xiàn)上傳文件功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04Bootstrap柵格系統(tǒng)使用方法及頁面調(diào)整變形的解決方法
這篇文章主要介紹了Bootstrap柵格系統(tǒng)使用方法及頁面調(diào)整變形的解決方法,需要的朋友可以參考下2017-03-03關(guān)于獲取DIV內(nèi)部內(nèi)容報錯的原因分析及解決辦法
這篇文章主要介紹了關(guān)于獲取DIV內(nèi)部內(nèi)容報錯的原因分析及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-01-01微信小程序?qū)崿F(xiàn)的貪吃蛇游戲【附源碼下載】
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)的貪吃蛇游戲,結(jié)合實例形式分析了微信小程序?qū)崿F(xiàn)貪吃蛇游戲功能的相關(guān)界面布局與代碼邏輯操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2018-01-01微信小程序動態(tài)評分展示/五角星展示/半顆星展示/自定義長度展示功能的實現(xiàn)
這篇文章主要介紹了微信小程序動態(tài)評分展示/五角星展示/半顆星展示/自定義長度展示的實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07