博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
防抖与节流
阅读量:6277 次
发布时间:2019-06-22

本文共 2652 字,大约阅读时间需要 8 分钟。

防抖

防抖技术即是可以把多个顺序地调用合并成一次,也就是在一定时间内,规定事件被触发的次数。

通俗一点来说,看看下面这个简化的例子:

// 简单的防抖动函数function debounce(func, wait, immediate) {    // 定时器变量    var timeout;    return function() {        // 每次触发 scroll handler 时先清除定时器        clearTimeout(timeout);//清除掉上一次的定时器回调函数,上次事件也就不会执行了。在500ms内,再次滚动,那上次的就清除掉了,不会执行。        // 指定 xx ms 后触发真正想进行的操作 handler        timeout = setTimeout(func, wait);    };};// 实际想绑定在 scroll 事件上的 handlerfunction realFunc(){    console.log("Success");}复制代码

采用了防抖动

window.addEventListener('scroll',debounce(realFunc,500));

封装上面的函数,更简洁

防抖动函数

function debounce(func, wait, immediate) {    var timeout;    return function() {        var context = this, args = arguments;        var later = function() {            timeout = null;            if (!immediate) func.apply(context, args);        };        var callNow = immediate && !timeout;        clearTimeout(timeout);        timeout = setTimeout(later, wait);        if (callNow) func.apply(context, args);    };};var myEfficientFn = debounce(function() {    // 滚动中的真正的操作}, 250);// 绑定监听window.addEventListener('resize', myEfficientFn);复制代码

防抖:

注意:上面的500ms,意思是:两次滚动事件的相隔时间必须大于500ms才能触发成功,而且是倒数第二次的事件触发成功的。如果所有的事件触发的时间间隔都小于500ms,那么就不会触发事件回调函数了,只有最后一次的事件回调能成功执行。复制代码

节流(Throttling)

  • 防抖函数确实不错,但是也存在问题,譬如图片的懒加载,我希望在下滑过程中图片不断的被加载出来,而不是只有当我停止下滑时候,图片才被加载出来。又或者下滑时候的数据的 ajax 请求加载也是同理。

  • 这个时候,我们希望即使页面在不断被滚动,但是滚动 handler 也可以以一定的频率被触发(譬如 250ms 触发一次),这类场景,就要用到另一种技巧,称为节流函数(throttling)。

  • 节流函数,只允许一个函数在 X 毫秒内执行一次。
  • 与防抖相比,节流函数最主要的不同在于它保证在 X 毫秒内至少执行一次我们希望触发的事件 handler。

  • 与防抖相比,节流函数多了一个 mustRun 属性,代表 mustRun 毫秒内,必然会触发一次 handler ,同样是利用定时器,看看简单的示例:

// 简单的节流函数	function throttle(func, wait, mustRun) {	    var timeout,	        startTime = Date.parse(new Date());//重点,这里是在页面加载后就执行的。不是等到滚动才执行。	        console.log(startTime);	    return function() {	        var context = this,	            args = arguments,	            curTime = new Date();	        clearTimeout(timeout);	        // 如果达到了规定的触发时间间隔,触发 handler	        if(curTime - startTime >= mustRun){	            func.apply(context,args);	            startTime = curTime;//重置开始时间startTime,把它设置成当前的时间	        // 没达到触发间隔,重新设定定时器	        }else{	            timeout = setTimeout(func, wait);	        }	    };	};	// 实际想绑定在 scroll 事件上的 handler	function realFunc(){	    console.log("Success");	}	// 采用了节流函数	window.addEventListener('scroll',throttle(realFunc,500,1000));复制代码
上面简单的节流函数的例子可以拿到浏览器下试一下,大概功能就是如果在一段时间内 scroll 触发的间隔一直短于 500ms ,那么能保证事件我们希望调用的 handler 至少在 1000ms 内会触发一次。注意:强调这句话:保证事件我们希望调用的 handler 至少在 1000ms 内会触发一次。最多也是一次。也就是说,在所有滚动事件的每两个相隔时间都加起来,从开始到结束滚动,每隔1000ms就是触发一次。比如从开始到结束,共经历1分钟,每隔1秒调用一次,总共大概调用60次。复制代码

参考链接:

转载于:https://juejin.im/post/5c6a7b5a6fb9a049fd106648

你可能感兴趣的文章
Java基本数据类型学习笔记
查看>>
Django的全文检索
查看>>
ItelliJ IDEA开发工具使用—创建一个web项目
查看>>
搞V6记录
查看>>
OC与js交互获取webview元素和赋值
查看>>
分布式锁的实现
查看>>
ctags --- 每天一个 Linux 命令
查看>>
页面加载新的东西到页面底部
查看>>
java执行命令行,路径有空格的解决办法
查看>>
test
查看>>
學習 React.js:用 Node 和 React.js 創建一個實時的 Twitter 流
查看>>
solr-4.10.4部署到tomcat6
查看>>
切片键(Shard Keys)
查看>>
淘宝API-类目
查看>>
virtualbox 笔记
查看>>
redis操作数据-sets
查看>>
Git 常用命令
查看>>
驰骋工作流引擎三种项目集成开发模式
查看>>
SUSE11修改主机名方法
查看>>
jdk6.0 + Tomcat6.0的简单jsp,Servlet,javabean的调试
查看>>