防抖debounce:
防抖是在定义N的时间范围内,如果没有触发事件则执行,如果触发了时间重置进行下一轮判断。
使用场景例如一个输入框有搜索功能,当键盘输入停止了一段时间,判定用户结束或暂停输入,然后再进行接口搜索,避免每次输入都进行一次接口调用。
手写防抖函数:
<input type="text" id="input1" /> <!-- 没有封装的写法 --> <script> let input1 = document.getElementById("input1"); let timer = null input1.addEventListener("keyup", function () { if (timer) { clearTimeout(timer); } timer = setTimeout(function () { console.log(input1.value); timer = null }, 500) }, false); </script>
<input type="text" id="input1" /> <script> // 封装防抖函数 let input1 = document.getElementById("input1"); input1.addEventListener(‘keyup‘, debounce(() => { console.log(input1.value); }), false) function debounce(fn, time = 500) { let timer = null return function () { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, time) } } </script>
节流throttle:
节流是连续触发事件,但是在N的时间里只进行一次触发,避免过度频繁触发事件。
使用场景例如拖拽DIV移动可以间隔一定时间进行移动的触发。
手写节流函数
<style> #div1 { border: 1px solid #000; width: 100px; height: 100px; } </style> <div id="div1" draggable="true"></div> <script> // 不做封装 let div1 = document.getElementById(‘div1‘); let timer = null; div1.addEventListener(‘drag‘, function (e) { if (timer) return timer = setTimeout(function () { console.log(e.offsetX, e.offsetY) timer = null }, 100) }, false) </script>
<style> #div1 { border: 1px solid #000; width: 100px; height: 100px; } </style> <div id="div1" draggable="true"></div> <script> // 进行封装 let div1 = document.getElementById(‘div1‘); div1.addEventListener(‘drag‘, throttle((e) => { console.log(e.offsetX, e.offsetY) }), false) function throttle(fn, time = 100) { let timer = null; return function () { if (timer) return timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, time) } } </script>