嗨哆嚒
嗨哆嚒
  • 发布:2020-09-07 15:50
  • 更新:2021-09-05 00:55
  • 阅读:8929

uniapp防抖节流封装

分类:HBuilderX

在防抖这一块,可以防止用户多次快速点击造成不必要的错误,基本原理是加个延时器,在时间到来前再次点击将重新计时。采用闭包实现变量不被销毁。具体代码如下:

//方法  
export const Debounce = (fn, t) => {  
    let delay = t || 500;   
    return function () {  
        let args = arguments;  
        let timer1 = null  
        // console.log(timer1);  
        if(timer1){  
            clearTimeout(timer1);  
        }  
        timer1 = setTimeout(() => {  
            fn.apply(this, args);  
            timer1 = null;  
        }, delay);  
    }  
};  

//调用  
/*import {Debounce} from '@/common/debounceThrottle.js'  
Debounce(() => {  
    //要执行的函数  
}, 200)() */

但我在实际使用中有个问题,timer在每次调用后就被销毁了,每次点击 timer都会重新被赋值为 null 。最终效果只剩了延迟触发,点几次,触发几次。研究了很久都没找到原因,最后,我采用了取巧的方法,将timer提到外面,定义为全局变量。虽然效果是达到了,但之前的问题仍不知道是哪里出了问题,希望有大佬能解惑。
下面是我取巧的方法:

/**  
 * 函数防抖 (只执行最后一次点击)  
 * @param fn  
 * @param delay  
 * @returns {Function}  
 * @constructor  
 */  
let timer1 = null; //防抖,  
let timer2 = null; //节流  
export const Debounce = (fn, t) => {  
    let delay = t || 500;   
    return function () {  
        let args = arguments;  
        // let timer1 = null  
        // console.log(timer1);  
        if(timer1){  
            clearTimeout(timer1);  
        }  
        timer1 = setTimeout(() => {  
            fn.apply(this, args);  
            timer1 = null;  
        }, delay);  
    }  
};  

// 使用  
/*import {Debounce} from '@/common/debounceThrottle.js'  
Debounce(() => {  
    //要执行的函数  
}, 200)() */  

/**  
 * 函数节流  
 * @param fn  
 * @param interval  
 * @returns {Function}  
 * @constructor  
 */  
export const Throttle = (fn, t) => {  
    let last;  
    let interval = t || 500;  
    return function () {  
        let args = arguments;  
        let now = +new Date();  
        if (last && now - last < interval) {  
            clearTimeout(timer2);  
            timer2 = setTimeout(() => {  
                last = now;  
                fn.apply(this, args);  
            }, interval);  
        } else {  
            last = now;  
            fn.apply(this, args);  
        }  
    }  
};  
2020-09-07 15:50 负责人:无 分享
已邀请:
5***@qq.com

5***@qq.com

this指向丢失

小糊涂酒仙

小糊涂酒仙

单独js文件封装 最简单方法,没有闭包带来的内存泄漏问题
也没有通过call 和 apply 来解决 this指向问题,代码还是写的实用,简单运行流畅的好。

// 防抖  
let t = null;  
export const debounce = function( fn, delay ) {  
    if( t !== null ) {  
        clearTimeout(t);  
    }  
    t = setTimeout(() => {  
        fn()  
    },delay)  
}
//调用  
debounce(() =>{  
    console.log("内容")  
},600)
  • zhangdaren

    特来点赞,我发现通过return函数的形式,用得不生效。。不知为啥

    2022-11-09 16:52

luch

luch

还得继续努力啊!
<br>
先搞懂闭包!
<br>
js 命名除了Class 类都是小驼峰
<br>
现在工具库都使用lodash.js,可以看一下。
<br>

/**  
 * 节流  
 */  
function throttle(fn, wait = 500, isImmediate = false) {  
  let flag = true;  
  if (isImmediate) {  
    return function() {  
      if (flag) {  
        fn.apply(this, arguments);  
        flag = false;  
        setTimeout(() => {  
          flag = true  
        }, wait)  
      }  
    }  
  }  
  return function() {  
    if (flag == true) {  
      flag = false  
      setTimeout(() => {  
        fn.apply(this, arguments)  
        flag = true  
      }, wait)  
    }  
  }  
}  

//防抖  
function debounce(fn, wait = 500, isImmediate = false) {  
  let timerId = null;  
  let flag = true;  
  if (isImmediate) {  
    return function() {  
      clearTimeout(timerId);  
      if (flag) {  
        fn.apply(this, arguments);  
        flag = false  
      }  
      timerId = setTimeout(() => {  
        flag = true  
      }, wait)  
    }  
  }  
  return function() {  
    clearTimeout(timerId);  
    timerId = setTimeout(() => {  
      fn.apply(this, arguments)  
    }, wait)  
  }  
}
ihshan12

ihshan12 - 好人一个

// 使用
/import {Debounce} from '@/common/debounceThrottle.js'
Debounce(() => {
//要执行的函数
}, 200)()
/

使用方式不对,你要把方法返回的函数绑定到事件中
<view @click="yourEvent">防抖</view>
methods:{
yourEvent:Debounce(() => {
//要执行的函数
}, 200)
}

船帆

船帆

需要节流的函数需要传参怎么办呢

1***@qq.com

1***@qq.com

首先不能用剪头函数,使用的时候也是。这样会导致this指向有问题的

  • 小糊涂酒仙

    这里可以使用箭头函数,因为在调用的时候用的是外部的this ,也就是实例的this。不用内部函数的this就可以使用箭头函数,要是使用内部的this指向就用普通函数,灵活运用就可以了,主要看使用的场景

    2021-09-06 01:12

  • 小糊涂酒仙

    如果觉得有问题,你可以试试在调用的部打印this,看看是不是和外部this指向一样,学艺不精

    2021-09-06 01:14

该问题目前已经被锁定, 无法添加新回复