函數防抖(debounce):當持續觸發事件時,必定時間段內沒有再觸發事件,事件處理函數纔會執行一次,若是設定的時間到來以前,又一次觸發了事件,就從新開始延時。javascript
函數節流(throttle):當持續觸發事件時,保證必定時間段內只調用一次時間處理函數。css
節流的定義應該比較好理解,舉例來講就是,你在瘋狂點擊短視頻裏面的「點亮紅心」按鈕,好比你10s點擊了1000次,可是節流的作法就是在這1000次的事件觸發過程當中,我規定1s才能真正的觸發紅心亮起的邏輯。因此10s內再快的點擊頻率,也只會亮起10顆紅心。html
防抖的定義看起來比較繞,咱們也舉例說明。舉例某寶或者某東的聯想搜索框,正常狀況,若是你短期內不停的敲擊鍵盤那麼每一次輸入的內容都會發送請求給服務端作聯想算法,而後不停返回數據,那麼下拉框看起來就會不停閃動,體驗不好,而且實際上不須要那麼高頻率的去發送請求,應該是當你中止了一個字或者一個詞或者一句話的輸入後再發送請求。因此防抖的作法,就是不管你多快的輸入(觸發事件),我只在這個週期的開始或者結束觸發一次事件中的邏輯。如此反覆,視爲防抖。java
咱們設定一個場景,有一個擁有固定寬高的div,監聽這個div的mouseover事件,觸發一次就+1,並將值填充到div中。 算法
<html>
<head>
<title></title>
<style type="text/css">
#container{
width: 400px;
height: 400px;
background-color: #333333;
color:#ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 34px;
font-weight: 600;
}
</style>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
var count = 1;
var container = document.getElementById('container');
function getUserAction(){
this.innerHTML = count++;
}
container.onmousemove = debounce(getUserAction,100,false);
function debounce(fn,wait,flag){
var timeout;
return function(){
var self = this;
clearTimeout(timeout);
if(flag){
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait);
if(callNow){
fn.apply(self);
}
}else{
timeout = setTimeout(function(){
fn.apply(self);
}, wait);
}
}
}
</script>
</body>
</html>
複製代碼
繼續引用上述場景,節流的目的是爲了在鼠標移動不停觸發mouseover的時候,+1的邏輯只在規定的周內執行一次(例:鼠標瘋狂滑動,只在1s內+1,不會在1s中內觸發兩次函數)瀏覽器
<html>
<head>
<title></title>
<style type="text/css">
#container{
width: 400px;
height: 400px;
background-color: #333333;
color:#ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 34px;
font-weight: 600;
}
</style>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
var count = 1;
var container = document.getElementById('container');
function getUserAction(){
this.innerHTML = count++;
}
container.onmousemove = throttle(getUserAction,1000);
//代理模式
function throttle(fn,wait){
var pre = 0;
return function(){
var self = this;
var now = +new Date();
if(now-pre>wait){
fn.apply(self);
pre = now;
}
}
}
</script>
</body>
</html>
複製代碼