### 前言
*****
防抖節流是很常見的兩個函數,實現原理都應該是一樣的,關鍵怎么寫,下面是一個簡單的理解,想要更深入學習,可前往這里進行[查看](http://www.hmoore.net/vvmily_king/vvmily/2478592)。
### 1、防抖
*****
在一段時間(delay)內重復執行,則執行最后一次。
使用場景:返回頂部、縮放瀏覽器窗口視圖重繪等。
```
// 具體原理,簡單實現
function debounce (fn,delay=300){
let clear = null
return function() {
if(clear) {
// 只要還在持續中,則清除setTimeout
clearTimeout(clear)
clear = null
}
clear = setTimeout(fn,delay)
}
}
```
* 具體實現
```
/**
* 防抖函數:多次觸發事件,事件處理函數只執行一次,并且在觸發操作后執行。
* 原理:利用閉包原理,就是函數需要在剛完成時需要被使用,賦值給一個變量,由這個變量去使用。
* @param {*} callback 回調函數
* @param {*} wait 延遲時間,默認500ms
* @param {*} immediate 是否立即執行
*/
export const debounce = (callback, wait = 500, immediate = true) => {
let timeout = null;
let debounced = function() {
let self = this;
timeout && clearTimeout(timeout);
if (immediate) {
let callNow = !timeout;
if (callNow) callback.apply(self, arguments);
timeout = setTimeout(() => {
timeout = null;
}, wait);
} else {
timeout = setTimeout(() => {
callback.apply(self, arguments);
}, wait);
}
};
debounced.cancel = function() {
clearTimeout(timeout);
timeout = null;
};
return debounced;
};
```
### 2、節流函數
*****
在連續執行過程中,每 delay時間內執行一次,所以整個操作會執行多次,約等`allTime / delay`次。
使用場景:鼠標拖動相關操作、縮放瀏覽器窗口視圖重繪等。
```
// 簡單原理,方便閱讀理解
function throttle(fn,delay=300) {
let isNot = true;
return function() {
if(!isNot){
return false // 在delay時間內,都不做處理
}
isNot = false
setTimeout(()=>{
fn()
isNot = true
},delay)
}
}
```
* 具體實現
```
/**
* 節流函數:觸發操作后,在間隔連續時間內只執行一次,過了規定間隔時間后,才進行下一次調用
* 原理:對函數進行間隔操作,在規定間隔時間內,如有重復操作,則清除掉本次操作
* @param {*} callback
* @param {*} wait 間隔時間,默認500ms
* @param {*} options = { leading: false, // 禁用第一次執行 trailing: false // 禁用停止觸發的回調 }
* @returns
*/
export const throttle = (callback, wait = 500, options = {}) => {
let time, context, args;
let previous = 0;
let later = function() {
previous = options.leading === false ? 0 : new Date().getTime();
time = null;
callback.apply(context, args);
if (!time) context = args = null;
};
let throttled = function() {
let now = new Date().getTime();
if (!previous && options.leading === false) previous = now;
let remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (time) {
clearTimeout(time);
time = null;
}
previous = now;
callback.apply(context, args);
if (!time) context = args = null;
} else if (!time && options.trailing !== false) {
time = setTimeout(later, remaining);
}
};
throttled.cancel = function() {
clearTimeout(time);
time = null;
previous = 0;
};
return throttled;
};
```
- 首頁
- 2021年
- 基礎知識
- 同源策略
- 跨域
- css
- less
- scss
- reset
- 超出文本顯示省略號
- 默認滾動條
- 清除浮動
- line-height與vertical-align
- box-sizing
- 動畫
- 布局
- JavaScript
- 設計模式
- 深淺拷貝
- 排序
- canvas
- 防抖節流
- 獲取屏幕/可視區域寬高
- 正則
- 重繪重排
- rem換算
- 手寫算法
- apply、call和bind原理與實現
- this的理解-普通函數、箭頭函數
- node
- nodejs
- express
- koa
- egg
- 基于nodeJS的全棧項目
- 小程序
- 常見問題
- ec-canvas之橫豎屏切換重繪
- 公眾號后臺基本配置
- 小程序發布協議更新
- 小程序引入iconfont字體
- Uni-app
- 環境搭建
- 項目搭建
- 數據庫
- MySQL數據庫安裝
- 數據庫圖形化界面常用命令行
- cmd命令行操作數據庫
- Redis安裝
- APP
- 控制縮放meta
- GIT
- 常用命令
- vsCode
- 常用插件
- Ajax
- axios-services
- 文章
- 如何讓代碼更加優雅
- 虛擬滾動
- 網站收藏
- 防抖節流之定時器清除問題
- 號稱破解全網會員的腳本
- 資料筆記
- 資料筆記2
- 公司面試題
- 服務器相關
- 前端自動化部署-jenkins
- nginx.conf配置
- https添加證書
- shell基本命令
- 微型ssh-deploy前端部署插件
- webpack
- 深入理解loader
- 深入理解plugin
- webpack注意事項
- vite和webpack區別
- React
- react+antd搭建
- Vue
- vue-cli
- vue.config.js
- 面板分割左右拖動
- vvmily-admin-template
- v-if與v-for那個優先級高?
- 下載excel
- 導入excel
- Echart-China-Map
- vue-xlsx(解析excel)
- 給elementUI的el-table添加骨架
- cdn引入配置
- Vue2.x之defineProperty應用
- 徹底弄懂diff算法的key作用
- 復制模板內容
- 表格操作按鈕太多
- element常用組件二次封裝
- Vue3.x
- Vue3快速上手(第一天)
- Vue3.x快速上手(第二天)
- Vue3.x快速上手(第三天)
- vue3+element-plus搭建項目
- vue3
- 腳手架
- vvmily-cli
- TS
- ts筆記
- common
- Date
- utils
- axios封裝
- 2022年
- HTML
- CSS基礎
- JavaScript 基礎
- 前端框架Vue
- 計算機網絡
- 瀏覽器相關
- 性能優化
- js手寫代碼
- 前端安全
- 前端算法
- 前端構建與編譯
- 操作系統
- Node.js
- 一些開放問題、智力題