防抖和節流的目的都是為了減少不必要的計算,不浪費資源,只在適合的時候再進行觸發計算。
一、函數防抖
-
定義
在事件被觸發n秒后再執行回調,如果在這n秒內又被觸發,則重新計時;典型的案例就是輸入搜索:輸入結束后n秒才進行搜索請求,n秒內又輸入的內容,就重新計時。 -
實現原理
函數防抖的基本思想是設置一個定時器,在指定時間間隔內運行代碼時清楚上一次的定時器,並設置另一個定時器,知道函數請求停止並超過時間間隔才會執行。 -
使用場景
文本框輸入搜索(連續輸入時避免多次請求接口) -
代碼實現
/**
* 函數防抖
*/
export function debounce(fn, delay) {
// 記錄上一次的延時器
var timer = null;
var delay = delay || 200;
return function() {
var args = arguments;
var that = this;
// 清除上一次延時器
clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(that,args)
}, delay);
}
}
二、函數節流
-
定義
規定在一個單位時間內,只能觸發一次函數,如果這個單位時間內觸發多次函數,只有一次生效; 典型的案例就是鼠標不斷點擊觸發,規定在n秒內多次點擊只有一次生效。 -
實現原理
其原理是用時間戳來判斷是否已到回調該執行時間,記錄上次執行的時間戳,然后每次觸發 scroll 事件執行回調,回調中判斷當前時間戳距離上次執行時間戳的間隔是否已經到達 規定時間段,如果是,則執行,並更新上次執行的時間戳, -
使用場景
resize、scroll、mousemove等事件觸發監聽
- 代碼實現
/**
* 函數節流
*/
export function throttle(fn,delay){
var lastTime;
var timer;
var delay = delay || 200;
return function() {
var args = arguments;
// 記錄當前函數觸發的時間
var nowTime = Date.now();
if (lastTime && nowTime - lastTime < delay) {
clearTimeout(timer);
timer = setTimeout(function () {
// 記錄上一次函數觸發的時間
lastTime = nowTime;
// 修正this指向問題
fn.apply(this, args);
}, delay);
}else{
lastTime = nowTime;
fn.apply(this, args);
}
}
}
三、在Vue中使用函數防抖實現輸入框搜索
效果圖如下
- 新建common.js文件
/**
* 函數防抖
*/
export function debounce(fn, delay) {
// 記錄上一次的延時器
var timer = null;
var delay = delay || 200;
return function() {
var args = arguments;
var that = this;
// 清除上一次延時器
clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(that,args)
}, delay);
}
}
- 在vue組件中引入
import {debounce} from '@/utils/common.js'
- 在組件中使用
<div class="white-search-bar">
<div class="search-bar-item">
<span class="iconfont icon-search"></span>
<input class="search-bar-input" :class="{'search-bar-focus':isSearchFocus}" type="text" maxlength="8" placeholder="應用搜索" v-model="keyword" @keyup="appSearch" @focus="onSearchFocus" @blur="onSearchBlur">
</div>
<span class="search-bar-btn" @click="appSearchCancel" v-if="isSearchFocus">取消</span>
</div>
methods:{
appSearch:debounce(function(){
this.getAppList()
},300)
}