问题隐患
- 一些短时间内频繁触发的事件会导致占用过多的资源,这时候我们设置一个触发间隔
- 频繁触发的事件,例如的
mousemove
(鼠标移动)、scroll
(滚动条),resize
等…
原理实现
- 初次调用函数时,设置一个定时器,在指定的
间隔
之后运行代码 - 第二次调用函数时(若小于
间隔
时间,定时器 尚未执行
),清除定时器并重设一个 - 如果定时器已经执行(
过了间隔时间
),此次操作就无意义。 - 目的是只有在执行函数的请求停止了一段时间(
间隔时间
)之后才执行。
function throttle(fn, obj) {
clearTimeout(fn.t);
fn.t = setTimeout(function(){
fn.call(obj);
}, 500);
}
function handler() {
}
window.onresize = function(){
throttle(handler, window);
};
应用
输入框验证(函数防抖)
- 注册时邮箱的输入框,随着用户的输入,实时判断邮箱格式是否正确
- 但每次的用户输入(按键弹起)都触发邮箱格式检测事件,造成了浪费
- 设置输入间隔大于800ms时(用户结束输入时),再执行检查邮箱格式
const filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
$("#email").on("keyup",checkEmail());
function checkEmail() {
let t = null;
return function() {
clearTimeout(t);
t = setTimeout(function() {
console.log('执行检查');
}, 800);
}
}
滚动加载(函数节流)
- 滚动事件的触发非常频繁
- 每次触发都去检查是否到页面底部,浪费资源
- 设置一个开关,一次只能有一个触发执行,并对执行设置计时一段时间再执行
- 执行完毕之后再解锁。这就是函数节流。
$(window).scroll(loadMore());
function loadMore() {
var canRun = true;
return function() {
if (!canRun) return;
canRun = false;
setTimeout(function() {
var docHeight = $(document).height();
var winHeight = $(window).innerHeight();
var scrollDistance = $(window).scrollTop();
if (docHeight - (winHeight + scrollDistance) <= 100) {
console.log('loading...');
}
canRun = true;
}, 600);
}
}
参考引用
浅谈函数节流
js对频繁触发事件的函数防抖和函数节流