JavaScript函數(shù)防抖與函數(shù)節(jié)流的定義及使用詳解
一、函數(shù)防抖(Debouncing)
1、基本概念
在觸發(fā)事件后的規(guī)定時(shí)間內(nèi)只能執(zhí)行一次,如果在規(guī)定時(shí)間內(nèi)又觸發(fā)了該事件。則會(huì)重新開(kāi)始計(jì)算規(guī)定時(shí)間;
2、算法思想
(1)首先定義一個(gè)函數(shù),函數(shù)進(jìn)入頁(yè)面立即執(zhí)行一次,且永遠(yuǎn)執(zhí)行最新的一次;
(2)返回一個(gè)匿名函數(shù);
(3)在匿名函數(shù)里使用計(jì)時(shí)器setTimeout設(shè)置規(guī)定時(shí)間;
(4)在使用clearTimeout來(lái)清除上一次的函數(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事件為滾動(dòng)條事件 屬于window對(duì)象
callback為回調(diào)函數(shù)
4、使用場(chǎng)景
防抖函數(shù)就是為了防止用戶進(jìn)行一些頻繁的點(diǎn)擊事件、輸入文字或者滾動(dòng)事件時(shí),對(duì)應(yīng)綁定的事件發(fā)生多次的場(chǎng)景,這些事件的觸發(fā)頻率很高,不做限制的話可能一秒執(zhí)行幾十次甚至幾百次,會(huì)造成不必要的浪費(fèi)。
下面用一個(gè)在網(wǎng)頁(yè)中經(jīng)常遇到的回到頂部案例說(shuō)明
代碼:
<!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);
}
}
//綁定滾動(dòng)條事件
window.onscroll = delbounce(returntop,200);
//onscroll 滾動(dòng)條事件 屬于window事件 不寫(xiě)到標(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ù),減少了對(duì)計(jì)算機(jī)資源的浪費(fèi)等等;
二、函數(shù)節(jié)流(Throlle)
1、基本概念
函數(shù)節(jié)流和函數(shù)防抖恰好相反,規(guī)定在一個(gè)單位時(shí)間內(nèi),只能調(diào)用一次函數(shù),如果在這個(gè)規(guī)定時(shí)間內(nèi)對(duì)此調(diào)用函數(shù),只能有一次被調(diào)用,相當(dāng)于子啊這個(gè)規(guī)定時(shí)間內(nèi)永遠(yuǎn)只會(huì)執(zhí)行第一次。
2、算法思想
(1)獲取剛進(jìn)入頁(yè)面的時(shí)間戳;
(2)獲取事件開(kāi)始發(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)入頁(yè)面時(shí)的時(shí)間戳
return function(){
let nowtime = new Date().getTime();//獲取滾動(dòng)條開(kāi)始滑動(dòng)的時(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():用來(lái)獲取當(dāng)前的時(shí)間戳
4、使用場(chǎng)景
函數(shù)節(jié)流可以運(yùn)用于所有的數(shù)據(jù)請(qǐng)求、按鈕和下拉刷新等等。
用一個(gè)登錄按鈕的使用的案例來(lái)說(shuō)明
代碼:
<!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ái)管理系統(tǒng)</h1>
<div class="email">
<input type="email" id="email" onblur="isEamil()" placeholder="請(qǐng)輸入郵箱..." 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="請(qǐng)輸入電話號(hào)碼..." 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="請(qǐng)輸入密碼..." 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 = "* 請(qǐng)輸入正確的郵箱!";
emailState = false;
isState();
return false;
}
email.style = "border:2px green solid";
document.getElementById("emailarr").innerHTML = "";
emailState = true;
isState()
return true;
}
//驗(yàn)證電話號(hào)碼格式是否正確
function isTel(){
let tel = document.getElementById("tel");
if(tel.validity.valueMissing){
email.style = "border:2px red solid";
document.getElementById("telarr").innerHTML = "* 電話號(hào)碼不能為空!";
telState = false;
isState();
return false;
}
if(tel.validity.patternMismatch){
tel.style = "border:2px red solid";
document.getElementById("telarr").innerHTML = "* 請(qǐng)輸入正確的電話號(hào)碼!";
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 = "* 請(qǐng)輸入正確的密碼!";
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)的對(duì)應(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ā)給后臺(tái)處理
//后臺(tái)返回兩種結(jié)果 error success
//將成功后的用戶信息進(jìn)行本地存儲(chǔ) 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ò)規(guī)定時(shí)間以后才能繼續(xù)點(diǎn)擊,進(jìn)行下一次登錄;
到此這篇關(guān)于JavaScript函數(shù)防抖與函數(shù)節(jié)流的定義及使用詳解的文章就介紹到這了,更多相關(guān)JavaScript函數(shù)防抖 節(jié)流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 一文學(xué)會(huì)JavaScript如何手寫(xiě)防抖節(jié)流
- 一文教你徹底學(xué)會(huì)JavaScript手寫(xiě)防抖節(jié)流
- JavaScript防抖與節(jié)流超詳細(xì)全面講解
- 利用JavaScript實(shí)現(xiàn)防抖節(jié)流函數(shù)的示例代碼
- JS中節(jié)流和防抖函數(shù)的實(shí)現(xiàn)及區(qū)別示例
- JavaScript防抖動(dòng)與節(jié)流處理
- JavaScript中防抖和節(jié)流的區(qū)別及適用場(chǎng)景
- Vue手寫(xiě)防抖和節(jié)流函數(shù)代碼詳解
相關(guān)文章
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
本文主要給大家詳細(xì)介紹Angular和Nodejs、socket.io的使用,以及如何使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室,需要的朋友可以來(lái)參考下2015-08-08
判斷用戶的在線狀態(tài) onbeforeunload事件
window.event.clientX和window.event.clientY 將捕捉當(dāng)前事件發(fā)生時(shí)鼠標(biāo)相對(duì)與窗口的桌面坐標(biāo),通常情況下IE的關(guān)閉按鈕都會(huì)在頁(yè)面的右上部分,所以點(diǎn)關(guān)閉的時(shí)候鼠標(biāo)的坐標(biāo)的Y坐標(biāo)一定是小于0的2011-03-03
javascript實(shí)現(xiàn)的元素拖動(dòng)函數(shù)宿主為瀏覽器
這篇文章主要介紹了javascript實(shí)現(xiàn)的元素拖動(dòng),將相應(yīng)的元素對(duì)象的引用傳到函數(shù)中2014-07-07
html+css+js實(shí)現(xiàn)xp window界面及有關(guān)功能
xp window界面及有關(guān)功能使用前端技術(shù)實(shí)現(xiàn)不可思議吧不夠該程序在IE調(diào)試的,其他瀏覽器可能有BUG,感興趣的朋友可以參考下哈,希望可以幫助到你2013-03-03
javascript實(shí)現(xiàn)控制瀏覽器全屏
這篇文章主要介紹了javascript實(shí)現(xiàn)控制瀏覽器全屏的代碼分享給大家,十分的實(shí)用,有需要的小伙伴可以參考下。2015-03-03
微信網(wǎng)頁(yè)授權(quán)并獲取用戶信息的方法
這篇文章主要介紹了微信網(wǎng)頁(yè)授權(quán)并獲取用戶信息的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07

