簡單的去抖(debounce)處理 和 節流(throttle) 附 原始碼
阿新 • • 發佈:2018-12-08
為什麼需要消抖、節流?
原因:事件頻繁觸發,頻繁的操作DOM,或者頻繁的向伺服器請求資料,嚴重消耗效能 或導致頁面崩潰
window
物件的resize
、scroll
事件- 拖拽時的
mousemove
事件 - 射擊遊戲中的
mousedown
、keydown
事件 - 文字輸入、自動完成的
keyup
事件
簡單debounce的例子:
<template> <div> <input type="number" v-model="num"> </div> </template> <script> import { debounce } from '@/utils' export default { data () { return { num: '' } }, watch: { // 如果不加debounce節流,會在num變化之後,立即執行 // num () { // console.log(this.num) // } // 加上debounce之後,num變化,會在1s之後,執行此函式 num: debounce(function () { console.log(this.num) }, 1000) } } </script>
debounce.js (引用 underscore.js)
function(func, wait, immediate) { var timeout, result; var later = function(context, args) { timeout = null; if (args) result = func.apply(context, args); }; var debounced = restArgs(function(args) { var callNow = immediate && !timeout; if (timeout) clearTimeout(timeout); if (callNow) { //如果立即呼叫,就設定一個定時,並且呼叫下方法。 timeout = setTimeout(later, wait); result = func.apply(this, args); } else if (!immediate) { //否則,更新定時的時間 timeout = _.delay(later, wait, this, args); } return result; }); debounced.cancel = function() { clearTimeout(timeout); timeout = null; }; return debounced; };
throttle.js 節流原始碼 (引用 underscore.js)
function(func, wait, options) { var timeout, context, args, result; var previous = 0; if (!options) options = {}; var later = function() { previous = options.leading === false ? 0 : _.now(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; var throttled = function() { var now = _.now(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; throttled.cancel = function() { clearTimeout(timeout); previous = 0; timeout = context = args = null; }; return throttled; };