您的位置:首页 > Web前端 > JavaScript

【javascript】滚动条事件优化->函数节流与去抖

2017-08-30 15:25 387 查看
为啥题目这样写,因为之前绑定滚动调试事件我是这样写的:

element.addEventListener('scroll', function() {
// do something
})


想过要优化这个,因为滚动事件,会触发很多次,里面的逻辑过于复杂,那么会很占用浏览器资源。但是不知道从何优化。

直到看到《JS高程》的函数节流,滚动条和事件和resize操作,是同样的道理,实际上我们需要做的操作只需要在滚动条事件完成或者resize的操作完成的一瞬间去执行我们的逻辑,中间的过程,我们的逻辑处理是没有意义的,因为它只是一个中间状态。

定义这样一个对象:

var processor = {
timeoutId: null,
//实际执行的代码
performProcessing: function(){
console.log('performProcessing 方法, 你的处理逻辑')
console.log('hello word')
},
//初始处理调用的方法
process: function() {
console.log('process方法')
clearTimeout(this.timeoutId)
var that = this
this.timeoutId = setTimeout(function(){
that.performProcessing()
}, 100)
}
}


我们在绑定滚动条事件可以这样:

window.onscroll = function(){
processor.process()
}


《JS高程3》上面用的是throttle节流来命名方法解决,但是按照lodash 和underscore 都是用的debounce防抖来解决这个问题。我们不纠结这个问题。先看《JS高程3》最后的封装方法

function throttle(method, context) {
clearTimeout(method.tId);
method.tId = setTimeout(function () { method.call(context); }, 100);
}


我们绑定一个滚动条滚动事件,并且指定我们的处理逻辑->print函数:

function print() { console.log('scroll handle logic') }
window.onscroll = function() { throttle(print) }


好到了这一步,我们已经能够解决类似的问题了,像scroll 和 resize事件的话,这类事件,实际上我们只需要最后一次去触发,不然我们scroll事件触发了100次,每次都得触发是不行的,只需要最后一次去触发。上面的函数实际上是利用定时器,比如我们1s之内连续触发了100次,我们每执行到throttle函数回去检查,print方法的tId是否存在,也就是上一个定时器是否存在,如果存在,则清除,连续的过程中,只要100ms内的连续操作,前面的定时器是被取消了的,最后一次没有被取消,在最后一次的事件触发的100ms之后会触发。(O__O …,大概就是这样,希望没搞晕你)

throttle 节流 和 debounce 防抖

lodash 和 underscore给我们提供了这些方法的扩展,并且有更多功能。

在resize 和 scroll 以及 ,防止用户重复点击提交数据,检查用户输入的数据(ajax请求) 都可以用到debounce防抖,这些操作只需要最后一次(或者第一次)的事件被触发。

在检测用户是否要滑动到页面底部(加载更多数据),这种情况需要用到throttle 节流,每隔多少时间去触发事件。

权威参考:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: