js防抖
什么是函数防抖
概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。
应用场景
(1) 用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源;
(2) window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次;
function debounce(fn, delay) {
let timer
return function(arges) {
clearInterval(timer);
timer = setTimeout(() => {
fn();
}, delay)
}
}
js节流
什么是节流
规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
应用场景
(1)鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
(2)在页面的无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据;
(3)监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断;
function throttle(fn, delay) {
let timer;
return function() {
if (!timer) {
timer = setTimeout(() => {
timer = null
fn()
}, delay);
}
}
}
和防抖区别是,防抖是间隔时间后最后执行一次,节流是按间隔时间连续执行.
时间戳截流——首节流
用最新触发的时间减去上一次回调执行的时间,如果大于等于 wait 则会执行回调
时间戳节流在第一次触发时会立刻执行。
在第一次操作的时候就会执行一遍fn,之后的操作如果时间不超过delay(例如2s)就不会在执行函数,理解为第一次执行,最后一次不执行
function throttle(func, wait) {
let previous = 0
return function throttled(...args) {
const ctx = this
const now = Date.now()
const remain = wait - (now - previous)
if (remain <= 0) {
func.apply(ctx, args)
previous = now
}
}
}
定时器节流——尾节流
指定时间之后执行回调,触发一个定时器之后,即使再次触发节流函数,也不会导致定时器推迟执行(事件循环或者同步阻塞会导致延迟执行,在这里不用考虑)。它不会清除已经开始的定时器,而是等待定时器被执行之后才再开始下一个定时器。
理解为第一次不执行,最后一次执行
function throttle(func, wait) {
let timeout = 0
return function throttled(...args) {
const ctx = this
// 如果已经是定时器定时阶段,则直接跳过,相当于忽略了触发
// 必须等到定时器到时间之后
if (!timeout) {
timeout = setTimeout(() => {
func.apply(ctx, args)
timeout = null
}, wait)
}
}
}
兼顾型节流,就能够在第一次,最后一次都执行代码。
function throttle(fn, delay){
let last=0;
let timer=null;
return function(){
let now=Date.now();
let reming=delay-(now-last);
clearTimeout(timer);//不管三七二十一,有定时器都先清除定时器
if(reming<0){
fn.apply(this, arguments);
last=now;
}else{
timer=setTimeout(()=>{
fn.apply(this,arguments);
}, reming);
}
}
}
本文共 675 个字数,平均阅读时长 ≈ 2分钟
hello word
666
学到了
666
666