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