JS - 函数防抖 & 函数节流

函数节流

限制一个函数在一定时间内只能执行一次(无论触发多少次,也都是每n秒后才执行一次)

主要用来防止频繁触发,优化程序性能,提高体验等等

 

方法一:时间戳

这个方法通过判断两次获取时间间隔长短来判断是否执行函数

每次触发时,只要到达指定时间点就会立即执行

触发函数后立即执行,等待n秒后才执行第二次

    var $button1 = document.getElementById('button1');
    var num = 0;
    $button1.addEventListener('click', throttle(throttleCallback, 1000));
function throttle(callBack, waitTime) { var time = Date.now(); return function() { var nowTime = Date.now(); var that = this; var args = arguments; /// 时间间隔判断 if ( nowTime-time >= waitTime ) { callBack.apply(that, args); // 触发方法后更新点击时间 time = Date.now(); } else {} } } // 执行函数 function throttleCallback(e) { e.stopPropagation(); // 取消事件冒泡 num++; console.log(num); }

 方法二:定时器

这个方法通过设置定时器延时执行函数

每次触发时,需要到指定时间后才执行

触发函数后不立即执行,等待n秒后才执行函数

    var $button2 = document.getElementById('button2');
    var num = 0;
    $button2.addEventListener('click', DispatcherTimer(DispatcherTimerCallBack, 1000));
    
    function DispatcherTimer(callBack, waitTime) {
        var timer = null;
        var wait = 200; // 保存时间变量, 为了让第一次点击时能立即执行
        return function() {
            var that = this;
            var grgs = arguments;
            // 判断是否存在定时器
            if(!timer) {
                timer = setTimeout(function(){
                    callBack.apply(that, grgs);
                    // 执行后清除定时器
                    clearTimeout(timer);
                    timer = null;
                }, wait);
            } else {}
            wait = waitTime; // 保存延迟时间
        }
    }
    // 执行函数
    function DispatcherTimerCallBack(e) {
        e.stopPropagation();//取消事件冒泡
        num++;
        console.log(num);
    }

 鼠标事件节流

    window.addEventListener('mousemove', moveThrottle(moveThrottleCallBack, 1000));
    function moveThrottle(callBack, waitTime) {
        var timer = null;
        return function() {
            var grgs = arguments;
            // 判断是否存在定时器
            if(!timer) { 
                timer = setTimeout(()=>{ 
                    callBack.apply(this, grgs);
                    // 执行完成后清除定时器,等待下一次执行
                    clearTimeout(timer);
                    timer = null;
                }, 1000); 
            }
        }
    }
    // 执行函数
    function moveThrottleCallBack(e){
        console.log('鼠标事件节流');
    }

 

函数防抖

当持续触发事件时,一定时间内没有再触发事件,事件函数才会执行一次。当在设定的时间之内又触发了事件函数,就会重新开始计时

既是在一些高频触发事件里,但其实只需要生效一次即可的函数,无论触发多少次,值运行最后一次

    var $button3 = document.getElementById('button3');
    $button3.addEventListener('click', debounce(function(){
        console.log("点击事件 函数防抖")
    }, 500));
    function debounce(fn, waitTime) {
        var timer = null; 
        return function() {
            var that = this;
            // 每次触发先清除定时器,再重新计算时间
            clearTimeout(timer);
            timer = null;
            timer = setTimeout(function(){
                fn.call(that);
            }, waitTime);
        }
    }

鼠标事件

  var t = null; // 定时器
  window.addEventListener('mousemove', moveDebounce);
  function moveDebounce(e){
    // 每次触发先清除定时器,再重新计算
    clearTimeout(t);
    t = null;
    t = setTimeout( ()=>{ move(e) }, 300 )
  }
  function move(e) {
    console.log('鼠标事件防抖');
  }

滚动事件

    var t = null;// 定时器
    window.addEventListener('scroll', scrollDebounce);
    function scrollDebounce(e) {
        // 每次触发先清除定时器,再重新计算
        clearTimeout(t);
        t = null;
        t = setTimeout( () => { scrollF(e) }, 300 );
    }
    function scrollF(e) {
        console.log("滚动事件");
    }

 

posted @ 2020-11-03 10:53  sanyekui  阅读(248)  评论(0编辑  收藏  举报