防抖和节流
防抖节流的作用
防抖和节流都是用来减少函数执行的频率,已达到项目性能的优化
防抖:
概念:
事件在触发一定时间后再执行回调,如果在这段时间又被触发了,则重新计时,等到计时到了再执行回调
应用场景:
1).输入框远程查询事件(防止边输入边执行后台请求,触发后台请求太多,浪费资源)
2)在线文档自动保存 (防止文档编辑过程中一直触发函数。而停止编辑后再触发性能比较好)
3)浏览器视口大小改变(防止在拖动窗口时一直触发某个方法,浪费资源。而等停止拖动后再触发性能比较好)
代码实现:
// 防抖函数的定义: 内部实际是一个闭包函数,可以通过调用debounce获取到内部的value值
const debounce = (fn, delay) => { let timer = null return function () { clearTimeout(timer) // 每次执行某个操作之前先清空timer timer = setTimeout(fn, delay) // 待延时时间到了再执行回调 } }
// 输入完成1s后再触发相应的回调 const inputEl = document.getElementById('inputEl') inputEl.oninput = debounce(function(event) { const value = event.target.value console.log('value的值是:', value) }, 1000)
节流:
概念:
在单位时间内多次触发某个事件,只执行一次
应用场景:
1)按钮提交事件 (也可以用loading实现,支付功能用节流更佳)
2)页面滚动事件
实现原理:设置一个时间,如果在规定时间内再次触发同一操作,则不执行该操作
代码实现:
const throttle(fn, delay) { let timer = null return function (evevt) { if (timer) return false; // 如果时间没到,不执行下一次操作 timer = setTimeouut(() => { // 如果时间到了,可以执行下一次操作,将timer清空,从头再来 clearTimeout(timer) timer = null fn(event) }, delay) } } cosnt btnEl = document.getElementById('btnEl') btnEl.addEventListener('click', throttle(function(event) { console.log("执行点击事件") }, 1000)
上述代码在每次执行点击操作均需要等待,而现实需求是第一次点击一次上一次点击结束后再点击都无需等待。所以有以下优化方案
优化后的代码实现:
function throttle (fn, delay) { let init = false // 引入一个参数记录状态 let timer; return (event) => { if (init) return init = true clearTimeout(timer) timer = setTimeout(() => { init = false }, delay) fn(event) } }