JavaScript函数节流(throttle)与函数去抖(debounce)
对于浏览器窗口大小改变的时候,来动态改变页面元素的大小,可以采用window的resize事件,实现代码:
<script type="text/javascript">
var n = 0;
function resizehandler(){
console.log(new Date().getTime());
console.log(++n);
} window.onresize = resizehandler;
</script>
功能能够实现,都是当我们用拖拽的方式改变浏览器大小的时候,控制台会不断打印执行resizehandler的函数的结果。
一次简单的拖拽会让resizehandler()函数执行很多次,实际在显示项目中resizehandler函数可能会很复杂,甚至会涉及到前后端的数据交互,所以一次拖拽执行很多次很明显是不能够接受的。
函数去抖
其实我们的本意只是窗口resize后页面做一些调整就可以了,而window的resize事件并不是在resize结束后才出发,具体的触发频率不是很清楚,但却在不停地调用,直到窗口大小不在变化。类似的机制还有鼠标的mousemove,都是在短时间内重复触发。
在《JavaScript高级程序设计》中有专门应对此问题的函数防抖
function throttle(method, context){
clearTimeout(method.tId);
method.tId = setTimeout(function(){
method.call(context);
}, 500);
}
原理很简单,利用定时器,让函数执行延迟500毫秒,在500毫秒内如果有函数又被调用则删除上一次的调用,这次调用500毫秒后执行,如此往复。这样刚才的代码可以改为:
<script type="text/javascript">
var n = 0;
function resizehandler(){
console.log(new Date().getTime());
console.log(++n);
} function throttle(method, context){
clearTimeout(method.tId);
method.tId = setTimeout(function(){
method.call(context);
}, 500);
} window.onresize = function(){
throttle(resizehandler, window);
};
</script>
这样的话执行就没有问题了。
函数防抖的另一种方法
预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个周期。
function throttle(method, dalay){
var timer = null;
return function(){
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
method.apply(context, args);
}, delay);
}
}
调用一下试试,一样的效果
<script type="text/javascript">
var n = 0;
function resizehandler(){
console.log(new Date().getTime());
console.log(++n);
} function throttle(method, delay){
var timer = null;
return function(){
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
method.apply(context, args);
}, delay);
}
} window.onresize = throttle(resizehandler, 500); //这里因为返回函数句柄,不用包装函数了。
</script>
比较
两种方法都是利用了setTimeout,不同的是第二种方法加入的函数延迟执行时间,这个在第一种方案中很容易也具有的功能,无非是加一个参数。
但是第一种方案把tId设为函数的一个变量保存,而第二种创建了闭包存储。个人觉得差距不大,很喜欢第一种,简单,高效。
新需求
百度首页输入自动提示一样的东西,我在text上绑定keyup事件,每次键盘弹起的时候自动提示,但是又不想提示那么频繁,于是我用了上面方法,但是悲剧了,只有挺直输入等500毫秒才会提示,在输入过程中根本就没有提示。看了一下代码,可不是嘛,只有用户会盲打,在500毫秒内按一下键盘,提示函数就会不断被延迟,这样只有停下来的时候才会提示,这就没有意义了。
能不能在函数节流的基础上间隔固定时间就执行一次?
函数节流
在网上搜了一下我们可以根据第二种下发(第一种函数拓展多个变量感觉有些不好)做些改动,添加一个参数作为到固定间隔必须执行。
function throttle(method, delay, duration){
var timer = null, begin = new Date();
return function(){
var context = this, args = arguments, current = new Date();
clearTimeout(timer);
if(current-begin >= duration){
method.apply(context, args);
begin = current;
} else {
timer = setTimeout(function(){
method.apply(context, args);
}, delay);
}
}
}
这样每次我们判断间隔了够久,要是超过设置时间则立即执行一次,以刚才的例子试一试效果
window.onresize = throttle(resizehandler, 100, 200);
这样,既没有频繁执行也没有就最后执行。
总结
对于函数节流在做动态响应用户行为方面有较大的使用频率,具体使用基础版本的函数节流还是改动版本的还要根据业务场景进行具体分析。
throttle和debounce均是通过减少实际逻辑处理过程的执行来提高事件处理函数运行性能的手段,并没有实质上减少事件的触发次数。 (逃)

JavaScript函数节流(throttle)与函数去抖(debounce)的更多相关文章
- [JavaScript] 函数节流(throttle)和函数防抖(debounce)
js 的函数节流(throttle)和函数防抖(debounce)概述 函数防抖(debounce) 一个事件频繁触发,但是我们不想让他触发的这么频繁,于是我们就设置一个定时器让这个事件在 xxx 秒 ...
- javascript 函数节流 throttle 解决函数被频繁调用、浏览器卡顿的问题
* 使用setTimeout index.html <html> <head> <meta charset="UTF-8"> <title ...
- js 函数节流throttle 函数去抖debounce
1.函数节流throttle 通俗解释: 假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯: 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟: ...
- JS中的函数节流throttle详解和优化
JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...
- 函数节流throttle和防抖debounce
throttle 函数节流 不论触发函数多少次,函数只在设定条件到达时调用第一次函数设定,函数节流 1234567891011 let throttle = function(fn,intervalT ...
- js 高程 函数节流 throttle() 分析与优化
在 js 高程 22.3.3章节 里看到了 函数节流 的概念,觉得给出的代码可以优化,并且概念理解可以清晰些,所以总结如下: 先看 函数节流 的定义,书上原话(斜体表示): 产生原因/适用场景: 浏览 ...
- 微信小程序:防止多次点击跳转(函数节流)
场景 在使用小程序的时候会出现这样一种情况:当网络条件差或卡顿的情况下,使用者会认为点击无效而进行多次点击,最后出现多次跳转页面的情况,就像下图(快速点击了两次): 解决办法 然后从 轻松理解JS函数 ...
- 【Javascript函数】节流throttle和间隔控制dbounce
一.throttle 函数节流,指把很小时间内触发的N多事件,节流成1个事件. 我们这里说的throttle就是函数节流的意思.再说的通俗一点就是函数调用的频度控制器,是连续执行时间间隔控制.主要应用 ...
- 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖
前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...
- JS的函数节流(throttle)
什么是函数节流? 介绍前,先说下背景.在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在 ...
随机推荐
- 在Storm的Toplogy中设置多数据源Spout
上代码:主要看main方法中的设置. 如下代码是一般情况下的设置方法...Trident中设置多数据源看对应的博客总结 /** * 指定多个数据源 * 数字累加求和 * 先添加storm依赖 */ ...
- 简单的字母全排列问题—递归法和STL法
问题描述:求全由小写字母组成的不超过200个字符序列的全排列 如输入序列bbjd,排列结果为: bbdj bbjd bdbj bdjb bjbd bjdb dbbj dbjb djbb jbbd jb ...
- GNU的编译器
GNU的编译器可以编译C或C++语言, 编译C语言使用gcc,编译C++语言使用g++ 如果是使用Linux或者Unix系统(Mac)可以使用以下命令: gcc -v 或者 g++ -v 来查看是否安 ...
- 如何做实时监控?—— 参考 Spring Boot 实现(转)
转自:http://blog.csdn.net/xiaoyu411502/article/details/48129057 随着 微服务 的流行,相比较以前一个大型应用程序搞定所有需求,我们现在更倾向 ...
- 软件架构设计学习总结(4):大数据架构hadoop
摘要:Admaster数据挖掘总监 随着互联网.移动互联网和物联网的发展,谁也无法否认,我们已经切实地迎来了一个海量数据的时代,数据调查公司IDC预计2011年的数据总量将达到1.8万亿GB,对这些海 ...
- Spring 环境与profile(一)——超简用例
什么是profile,为什么需要profile? 在开发时,不同环境(开发.联调.预发.正式等)所需的配置不同导致,如果每改变一个环境就更改配置不但麻烦(修改代码.重新构建)而且容易出错.Spring ...
- SAP HANA项目过程中优化分析以及可行性验证
在项目开发过程中,经常会遇到HANA模型运行效率的问题: 以我们项目为例,HANA平台要求模型运行时间不能超过10秒,但是在大数量和计算逻辑复杂的情况下(例如:ERP中的BKPF和BSEG量表的年数据 ...
- 并发编程—— FutureTask 源码分析
1. 前言 当我们在 Java 中使用异步编程的时候,大部分时候,我们都会使用 Future,并且使用线程池的 submit 方法提交一个 Callable 对象.然后调用 Future 的 get ...
- CPU简单科普
CPU简单科普 本文仅限于对小白科普. 误解一:CPU使用率和硬盘使用率一样. 误解二:一台电脑只有一个CPU. 误解三:CPU的核数,就是CPU的数量. 误解三:CPU主频越高越厉害:CPU核数越多 ...
- 表格行与列mouse经过时高亮显示
Insus.NET有在asp.net mvc应用程序,练习jQuery与css时,实现了<表格行mouse经过时高亮显示>http://www.cnblogs.com/insus/p/37 ...