JavaScript 优化 — 事件节流

问题隐患

  • 一些短时间内频繁触发的事件会导致占用过多的资源,这时候我们设置一个触发间隔
  • 频繁触发的事件,例如的 mousemove(鼠标移动)、scroll(滚动条),resize 等…

原理实现

  • 初次调用函数时,设置一个定时器,在指定的 间隔 之后运行代码
  • 第二次调用函数时(若小于 间隔 时间,定时器 尚未执行),清除定时器并重设一个
  • 如果定时器已经执行(过了间隔时间),此次操作就无意义。
  • 目的是只有在执行函数的请求停止了一段时间(间隔时间)之后才执行。
/**
 * [throttle 节流]
 * @param  {Function} fn  [执行函数]
 * @param  {[object]} obj [调用对象]
 * @return {[type]}       [undefined]
 */
function throttle(fn, obj) { 
    // 清除定时器
    clearTimeout(fn.t);
    // 设置定时器
    fn.t = setTimeout(function(){
        // 重新指向调用对象
        fn.call(obj);
    }, 500); // 设置间隔时间
}

// 调用
function handler() {
    // code...
}
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对频繁触发事件的函数防抖和函数节流

猜你喜欢

转载自blog.csdn.net/wildye/article/details/80134694