我们知道,js
有些事件例如resize
,mousemove
等是会不间断触发的,例如我们简单的一个scroll
事件:
function scrollFn() {
console.log(1)
}
window.onscroll = scrollFn
我们需要在滚动的时候去做一些事情,如上图可见,我们只是简单的console
,在一次滚动过程中函数即执行了将近20
次,如果这个函数有更为复杂的方法,比如操作dom
或者其他交互,会严重影响性能。
为了避免这个问题,我们一般会使用定时器来对函数进行节流。
在javascript高级程序设计中,定义了一个函数节流方法,如下:
function throttle(method,context) { // 执行函数、哪个作用域中执行
clearTimeout(method.tId);
method.tId = setTimeout(function() {
method.call(context)
},300)
}
throttle
函数接收两个参数,即要执行的函数及执行环境,如果执行环境未定义,默认则为windows
。在这个函数中,会在第一次执行时为method
一个定时器属性,在指定时间间隔(300
)内再次执行时会清楚上一次定义的定时器并创建新定时器知道停止。
函数节流
函数预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。
function throttle(method, duration) {
let begin = new Date()
return function () {
const context = this, args = arguments
let current = new Date()
if (current - begin >= duration) {
method.apply(context, args)
begin = current
}
}
}
function resize() {
let n = 1
console.log(++n)
}
window.onresize = throttle(resize, 5000)
函数防抖
函数调用n
秒后才会执行,如果函数在n
秒内被调用的话则函数不执行,重新计算执行时间。
function debounce(method, delay) {
let timer = null
return function () {
const context = this, args = arguments
clearTimeout(timer)
timer = setTimeout(function () {
method.apply(context, args)
}, delay)
}
}
function resize() {
let n = 1
console.log(++n)
}
window.onresize = debounce(resize, 500)