js 实现防抖和节流方法

防抖和节流

解决的就是事件被多次触发时,只执行最后一次事件,核心思想为了提升性能,减少DOM操作。

函数节流:指某些代码不可以在没有间断的情况下连续重复执行。
函数防抖:是指,一个频繁触发的事情只让最后一次执行。

区别:

函数节流
函数节流:一个函数执行一次后,只有大于设定的执行周期后才会执行第二次。有个需要频繁触发函数,出于优化性能角度,在规定时间内,只让函数触发的第一次生效,后面不生效。

时间戳实现函数节流

根据函数节流的原理,我们也可以不依赖 setTimeout实现函数节流。
function throttle(fn, delay) {
    // 记录上一次函数触发的时间
    var lastTime = 0;
    return function() {
        // 记录当前函数触发的时间
        var nowTime = Date.now();
        if (nowTime - lastTime > delay) {
        // 修正this指向问题
            fn.call(this);
        // 同步时间
          lastTime = nowTime;
        }
    }
}

测试代码:
// test
function testThrottle(e, content) {
    console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 1000); // 节流函数
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // 给节流函数传参
}

定时器实现函数节流

function throttle(fn, delay) {
    var timer;
    return function () {
        var _this = this;
        var args = arguments;
        if (timer) {
            return;
        }
        timer = setTimeout(function () {
            fn.apply(_this, args);
            timer = null; // 在delay后执行完fn之后清空timer,此时timer为假,
            throttle触发可以进入计时器
        }, delay)
    }
}

测试代码:
function testThrottle(e, content) {
    console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 2000); // 节流函数
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // 给节流函数传参
}

如果一直在浏览器中移动鼠标(比如10s),则在这10s内会每隔2s执行一次testThrottle,这就是函数节流。

函数防抖
防抖函数:一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效。

function debounce(fn, delay) {
    var timer = null; 
    return function () {
        var _this = this; // 取debounce执行作用域的this
        var args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            fn.apply(_this, args); // 用apply指向调用debounce的对象,
            相当于_this.fn(args);
        }, delay);
    };
}

测试代码:
function testDebounce(e, content) {
    console.log(e, content);
}
var testDebounceFn = debounce(testDebounce, 1000); // 防抖函数
document.onmousemove = function (e) {
    testDebounceFn(e, 'debounce'); // 给防抖函数传参
}

vue 中使用

// 防抖
export function _debounce(fn, delay) {

    var delay = delay || 200;
    var timer;
    return function () {
        var th = this;
        var args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            timer = null;
            fn.apply(th, args);
        }, delay);
    };
}
// 节流
export function _throttle(fn, interval) {
    var last;
    var timer;
    var interval = interval || 200;
    return function () {
        var th = this;
        var args = arguments;
        var now = +new Date();
        if (last && now - last < interval) {
            clearTimeout(timer);
            timer = setTimeout(function () {
                last = now;
                fn.apply(th, args);
            }, interval);
        } else {
            last = now;
            fn.apply(th, args);
        }
    }
}

引用

import { _debounce } from "@/utils/common";

使用

 methods: {
    // 改变场数
    changefield: _debounce(function(_type, index, item) {
        // do something ...
    }, 200)
  }

// once 执行一次函数

function once(fn){
    let done = false;
    return function(){
        if(!done){
            done = true;
            fn.apply(this, arguments);
        }
    }
 }
 
 let pay = once(function(money){
    console.log(`花费了: ${money}`)
 })
 
 pay(3)
 pay(3)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值