函数防抖和节流
防抖和节流
防抖和节流主要目的就是防止一个事件频繁触发或频繁使用DOM。比如scroll事件,滚动事件通常频繁触发,上一次回调没有执行完,下一次的事件就触发了,导致出现的页面抖动现象。
函数防抖的主要思想是让事件不立即触发
函数节流的主要思想是每次触发后间隔 n 秒后再触发
防抖
让事件不立即触发
主要思路是,创建一个定时器,事件触发 x 时间后再执行方法,若短时间内频繁重复事件,则删除上一个定时器,重新创建新的定时器
如下:
// 三个参数 // method:Function 可能会导致抖动的方法 // args?:Array (可选),方法的参数,数组形式 // context?:Object (可选),方法需要绑定的this const debounce = function (method, args, context){ let timer = null return function(){ clearTimeout(timer) // 通过 bind 绑定zthis,同时传参。注:不能用apply和call,因为会直接执行,bind不会直接执行 timer = setTimeout(method.bind(context || this, ...(args||[])), 1000) } }
// 测试回调函数1:无参数,无需改变 this 指向 function test1(){ console.log("test1:", 1) }
// 测试回调函数2:有参数,无需改变 this 指向 function test2(a, b, c){ console.log("test2:", a, b, c) }
// 测试回调函数3:有参数,有 this function test3(a, b, c){ console.log("test3:", a, b, c) console.log("this.x:", this.x); }
// 测试对象,用于 this.x let o = { x: "00000" } // test1: 1 window.addEventListener("scroll", debounce(test1)) // test2: 1 2 3 window.addEventListener("scroll", debounce(test2, [1,2,3])) // test3: 1 2 3 // this.x: 00000 window.addEventListener("scroll", debounce(test3, [1,2,3], o))
节流
每次触发后间隔 n 秒后再触发
主要思路是,通过定时器让事件触发后短期内禁止再次触发,需要隔一定时间才能再触发
如下:
const debounce = function (method, args, context){ let timer = null return function(){ if(!timer){ timer = setTimeout(()=>{ // 注意,此时不能用 bind,因为此时需要执行而非传入回调函数 method.call(context || this, ...(args||[])) timer = null }, 1000) } } }