防抖和节流
什么情况下会用到防抖和节流呢?在绑定一些事件的时候,如resize,鼠标移动等。。
就是持续触发事件的时候。
有时候我们并不希望在事件持续触发时,频发的去执行函数,所以需要用到防抖和节流。
什么是防抖?(防抖节流插件:underscore.js
)
-
原理:
事件响应函数在一段时间后才执行,如果在这段时间内再次调用,则重新计算执行时间;当预定的时间内没有再次调用该函数,则执行响应函数。
-
一般防抖还是用的比较多的
-
应用场景:
- scroll事件滚动触发
- 搜索框输入查询
- 表单验证
- 按钮提交事件
- 浏览器窗口缩放,resize事件
-
例子:
// 防抖函数 function debounce(func, wait, immediate) { let timeout; return function () { // event指向问题 let args = arguments; // 改变函数this指向问题 let context = this; clearTimeout(timeout); if (immediate) { // 立即执行 let callnow = !timeout; timeout = setTimeout(() => { timeout = null; }, wait); // 立即执行 if (callnow) func.apply(context, args); } else { // 不会立即执行 timeout = setTimeout(() => { func.apply(context, args); }, wait); } }; } let count = 0; let container = document.querySelector("#container"); function doSomeThing(e) { console.log(e); container.innerHTML = count++; } container.onmousemove = debounce(doSomeThing, 300, false);
什么是节流?
-
原理:如果持续触发事件,每隔一段时间,只执行一次事件
-
应用场景:
- dom元素的拖拽功能实现
- 射击游戏
- 计算鼠标移动的距离
- 监听scroll滚动事件
-
例子:
// 节流函数 function throttle(func, await, options) { let timeout, args, context; let old = 0; if (!options) options = {}; let later = function () { old = new Date().valueOf(); timeout = null; func.apply(context, args); }; return function () { // event指向问题 args = arguments; // 改变函数this指向问题 context = this; let now = new Date().valueOf(); if (!options.leading && !old) { old = now; } // 第一次立即执行 if (now - old > await) { if (timeout) { clearTimeout(timeout); timeout = null; } func.apply(context, args); old = now; }else if (!timeout && options.trailing) { timeout = setTimeout(later, await); } }; } let count = 0; let container = document.querySelector("#container"); function doSomeThing(e) { console.log(e); container.innerHTML = count++; } container.onmousemove = throttle(doSomeThing, 1000, { leading: true, trailing: false, });