(debounce)防抖和(trottle)节流

(debounce)防抖 :

在一段时间内 控制事件触发一次 。如果在时间内触发 那么会重新计时 过完时间后在可以触发;

前置防抖

    <button class="btn1">点击前置防抖</button>
    <button class="btn3">点击前置防抖2</button>
    <button class="btn2">点击后置防抖</button>
    <input type="text" class="myinput" />

        先执行函数 在防抖

      let timer = null;

        document.querySelector(".btn1").onclick = function () {
            // console.log(timer);
            if (!timer) {
                console.log(1111);
            }
            clearTimeout(timer);
            timer = setTimeout(() => {
                timer = null;
            }, 1000);
        }

        提取防抖逻辑 写一个通用函数 ,提高复用性;

    document.querySelector(".btn1").onclick = debounce(function () {

            console.log(111, this);
        }, 1000);

    document.querySelector(".btn3").onclick = debounce(function () {
            console.log(3333);
        }, 2000);  
      
    function debounce(fn, delay) {
            let timer = null;
            return function () {
                // console.log(this);
                if (!timer) {
                    // fn();
                    // fn.call(this);
                    fn.apply(this, arguments);
                }
                clearTimeout(timer);
                timer = setTimeout(() => {
                    timer = null;
                }, delay);
            }
        }

 后置防抖

        先防抖 在执行函数

        let timer2 = null;  // 变量污染 ;
        document.querySelector(".btn2").onclick = function () {
            // console.log(timer);
            clearTimeout(timer2);
            timer2 = setTimeout(() => {
                timer2 = null;
                console.log(2222);
            }, 1000);
        }
        document.querySelector(".btn2").onclick = debounce2(function () {
            console.log("后置防抖");
        }, 2000);

        function debounce2(fn, delay) {
            let timer = null;
            return function () {
                clearTimeout(timer);
                timer = setTimeout(() => {
                    timer = null;
                    // console.log(2222);
                    fn.apply(this, arguments);
                }, delay);
            }
        }

(trottle)节流

        控制事件执行的频率 ,在一段时间内重复执行;

        let startTime = new Date().getTime(); //时间戳 
        document.onmousemove = function () {
            let nowTime = new Date().getTime();
            if ((nowTime - startTime) > 500) {
                console.log(11111);
                startTime = new Date().getTime();
            }
        }
        document.onmousemove = trottle(function(){
            console.log("mousemove")
        },1000);


        document.querySelector(".myinput").oninput = trottle(function(){
            console.log(this.value);
        },1000);



        // 提取逻辑 写一个 通用的节流函数  
        function trottle(fn, delay) {
            let startTime = new Date().getTime();
            return function () {
                let nowTime = new Date().getTime();
                if ((nowTime - startTime) > delay) {
                    fn.apply(this,arguments);
                    startTime = new Date().getTime();
                }
            }
        }

用玩游戏的思路去看待防抖和节流大概就是 :防抖:施法前摇。    节流 :技能的cd。

通用函数中涉及到了一些闭包相关概念,以下对该问题进行简述;

闭包 :函数对于外部环境context(上下文)的引用 ;

        var num = 10; // 在内存中不会被销毁;
        function test(){
            console.log(num);
        }

        test();
        function test(){
            var num = 10; //被内存缓存起来
            return function(){
                num++;
                console.log(num)
            }
        }
        // test();
        // console.log(num);
        let fn = test();
        fn();
        fn();
        fn();
        function test(){
            console.log("test");
        }

        // 让test函数只能执行一次;
        function once(fn){   // 记录 test的执行状态;
            let flag = false;
            return function(){
                if(!flag){
                    fn();
                    flag = true;
                }else{
                    console.log("已经执行过了");
                }
            }
        }

        let myfn = once(test);
        myfn();
        myfn();
        myfn();

    高阶函数 :有函数作为输入 或者输出的函数  ;

        以函数作为输入;也把输入的这个函数叫回调函数 callback

        function fn1(fn){
            fn();
        }

        fn1(function(){})
        // 以函数作为输出 
        function fn2(){
            var a = 20;
            return function(){
                console.log(a);
            }
        }

一个防抖节流的示范

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            height: 3000px;
        }
    </style>
</head>
<body>
    <button>点击</button>
    <script>
const oBtn=document.querySelector("button");

        // 函数防抖
//         let t;
// window.onscroll=function(){
//     clearInterval(t);
//     t=setInterval(function(){
//         console.log(2022);
//         clearInterval(t);
//     },1000)

// }


// 函数节流  disabled
// oBtn.onclick=function(){
//     oBtn.disabled=true;
// let count=3;
// oBtn.innerHTML=count+"s之后可以再次点击";
// let t=setInterval(function(){
//     count--;
//     oBtn.innerHTML=count+"s之后可以再次点击";
//     if(count<=0){
//         clearInterval(t);
//         oBtn.disabled=false;
//         oBtn.innerHTML="点击";
//     }
// },1000)

// }


// 函数节流   flag
let flag=true;
oBtn.onclick=function(){
    if(flag){
        flag=false;
        let count=3;
        oBtn.innerHTML=count+"s之后可以再次点击";
        let t=setInterval(function(){
            count--;
            oBtn.innerHTML=count+"s之后可以再次点击";
            if(count<=0){
                clearInterval(t);
                flag=true;
                oBtn.innerHTML="点击";
            }
        },1000)
    }
}



    </script>
</body>
</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值