函数节流
Posted we are young
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数节流相关的知识,希望对你有一定的参考价值。
1. 函数节流:
- 由于dom操作极其昂贵,所以尝试过多的dom操作有可能会将浏览器搞崩溃,比如onresize、onscroll这类事件操作;
- 为了解决这个问题,引出函数节流的概念(某些代码不可以在没有间断的情况下连续重复执行);
- 方案:第一次调用函数创建一个定时器,在指定时间之后执行代码;在第二次调用时,清除掉前一次的定时器并重新设置一个;
- 这种方案下,如果第一个定时器已经执行,这个操作就没意义;如果第一个没执行,则将其替换为新的定时器;目的是只有在执行函数的请求停止一段时间后才执行;
- 适用于代码是周期执行的,但是你不能控制请求执行的速率;
- 函数节流让一个函数只有在你不断触发后停下来歇会才开始执行,中间你操作得太快它直接无视。
// 函数节流 function throttle(method, context) { clearTimeout(method.tid); // mthod是真实要执行的函数,context是执行的作用域(默认window) method.tid = setTimeout(function() { method.call(context) // 确保方法在适当的环境中执行 }, 100); } // onscroll时函数节流 function scrollFun() { var marginBot = 0; if (document.documentElement) { marginBot = document.documentElement.scrollHeight - (document.documentElement.scrollTop+document.body.scrollTop) - document.documentElement.clientHeight; } else { marginBot = document.body.scrollHeight - document.body.scrollTop - document.body.clientHeight; } if(marginBot <= 0) { // 滚动到底部加载数据操作 } } window.onscroll = function() { throttle(scrollFun); }
2. 函数防抖
-
如果我们不希望每次都是要事件结束后等待延迟时间后执行回调;
- 我们可以先给定一个时间段duration,过了这个时间段以后我们执行相应的操作;如果没有过这个时间段,那么就按照函数节流的思路,开关定时器就ok。
function debounce(method, delay, duration){ var timer = null, stime = new Date(); // 记录下开始执行函数的时间 return function() { var context = this, args = arguments, ctime = new Date(); // 记录下当前时间 clearTimeout(timer); // 函数节流里的思路 // 记录下的两个时间相减再与duration进行比较 if (ctime - stime >= duration) { method.apply(context, args); stime = ctime; } else { timer = setTimeout(function(){ method.apply(context, args); }, delay); } } } window.onresize = debounce(method, 50, 100); // 50ms的间隔内连续触发的调用,后一个调用会把前一个调用的等待处理掉,但每隔100ms至少执行一次
3. 滚动实例区分下:
normal:滚动会立即触发事件执行;
throttle: 延迟100ms直到100ms以内没有事件触发之后执行,这样如果一直在操作,有可能一直不会触发事件发生;
debounce:50ms的间隔内连续触发的调用,后一个调用会把前一个调用的等待处理掉,但每隔100ms至少执行一次。
以上是关于函数节流的主要内容,如果未能解决你的问题,请参考以下文章