天天看点

js防抖 和节流函数

最近搞了一个input 输入框 自动完成的效果

大概效果如下链接:

http://www.jq22.com/jquery-info438

然后我是用keyup() 方法监听的input 输入框的值,只要键盘抬起就会去请求接口!所以啊,频率太快,恶心至极。所以要想办法搞丫的一下。不然看着太难受。也影响性能!

突然想起来 vue 的官网上有一个小案例,就是大概这个效果,输入内容的时候不去请求,等输入停下以后,才会去请求,

https://cn.vuejs.org/v2/guide/computed.html 效果在页面最底部,

但是他用的是 Lodash 的 _.debounce 函数来限制的频率操作。而我做的是一个很小的效果,感觉大材小用了(其实是懒)。

有了眉目 顺藤摸瓜,百度一番后了解到了 防抖和节流这两个概念。然后在网上找到了下边的两个方法记录下来

先普及下概念

函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

不有的想起了一个场景,

输入框内容校验 ,类似百度联想词

通过监听 scroll 事件,检测滚动位置,根据滚动位置显示返回顶部按钮

通过监听 resize 事件,对某些自适应页面调整DOM的渲染(通过CSS实现的自适应不再此范围内)

通过监听 keyup 事件,监听文字输入并调用接口进行模糊匹配

函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

在来个不由得想起了一个场景,说这话的时候多少有点尴尬。

抢购的时候。

画外音:任何脱离了业务场景的技术都是耍流氓,防抖也好,节流也罢,适合他的业务场景才是最好的

分析需求。

防抖:我们应该封装一个函数,这个函数需要哪些参数,看上边概念的两个关键字:一定时间(delay),处理函数(fn)。

function debounce(fn, dealy) {
         let timer = null
         return function () {
             //上来的给他清理掉哦,感兴趣的同学可以去研究下setTimeout(),和 
             // clearTimeout
             clearTimeout(timer)
             //在这个时间内我只调用一次事件处理函数,是不是达到防抖的目的呢。
             timer = setTimeout(function () {
                 fn.apply(this, arguments)
             }, dealy)
         }
     }
    // 功能实现,800ms之内,你触发多少次我只执行一次,就是这么任性
    input.oninput = debounce(fn,800)
           

节流:我们还是应该封装一个函数,需要参数,事件处理函数(fn),一定时间(wait)

function throttle(fn, wait) {
         //定义一个事件为0,第一次肯定会执行
         let lastTime = 0
         return function () {
             //拿到从1970年到现在的时间戳
             let nowTime = new Date.getTime()
             //在这个时间内我才触发事件处理函数,是不是起到节流的目的呢。
             if (nowTime - lastTime > wait) {
                 fn.apply(this, arguments)
                 lastTime = nowTime
             }
         }
     }
     //功能实现,不好意思,300ms这个时间之内,点击我多少次,我就给你处理一次,sorry
     button.click = throttle(fn,300)
           

最后发现用keyup 来监听input 输入框的内容实在是有点不合适, 想到了 js 原生的 oninput() 方法

教程 网址: http://www.runoob.com/jsref/event-oninput.html

jq 有响应的bind() 的方法可以绑定 oninput 但是有网友说兼容性不太好,建议还是用原生的oninput() 方法

继续阅读