javascript中的函数节流和函数去抖
带着问题去尝试
首先我们要知道为什么要用到函数节流和函数去抖?我们带着以下的疑问来进行分析!
1.比如搜索框,你会用到什么事件(change、blur、keyup等)?去做什么效果?
2.再比如scroll滚动事件,怎么去触发?是滚一段距离触发一次?还是滚一圈触发一次?还是滚一次触发一次?
3.还包括mouseover事件是怎么触发呢?
......
场景实例
函数节流和去抖的出现场景,一般都伴随着客户端 DOM 的事件监听。举个例子,实现一个原生的拖拽功能(不能用 H5 Drag&Drop API),需要一路监听 mousemove 事件,在回调中获取元素当前位置,然后重置 dom 的位置(样式改变)。如果我们不加以控制,每移动一定像素而触发的回调数量是会非常惊人的,回调中又伴随着 DOM 操作,继而引发浏览器的重排与重绘,性能差的浏览器可能就会直接假死,这样的用户体验是非常糟糕的。我们需要做的是降低触发回调的频率,比如让它 500ms 触发一次,或者 200ms,甚至 100ms,这个阈值不能太大,太大了拖拽就会失真,也不能太小,太小了低版本浏览器可能就会假死,这样的解决方案就是函数节流,英文名字叫「throttle」。函数节流的核心是,让一个函数不要执行得太频繁,减少一些过快的调用来节流。
说完函数节流,再看它的好基友函数去抖(debounce)。思考这样一个场景,对于浏览器窗口,每做一次 resize 操作,发送一个请求,很显然,我们需要监听 resize 事件,但是和 mousemove 一样,每缩小(或者放大)一次浏览器,实际上会触发 N 多次的 resize 事件,用节流?节流只能保证定时触发,我们一次就好,这就要用去抖。简单的说,函数去抖就是对于一定时间段的连续的函数调用,只让其执行一次。
实例了解
下面就让我们来了解throttle(节流) 和 debounce(去抖)
1.throttle节流,scroll和mouseover亦或者其他方式,每次移动都会触发代码效果,但是这些效果太密集了,占用了系统资源,计算机的计算能力是有限的,我们写的代码应该尽可能的优雅。
2.debounce去抖,本意是从按键去抖过来的,让我们的用户正确的操作之后才去执行代码,且只会执行一次,比如当我们做文本输入的时候,如果用keyup我们不是去节流,而是去判断用户停止了输入。
3.节流保证在一定时间内,只能触发一次。如果我们只要触发一次,这就是去抖。代码上来看差距不是很大。
直接试一下:
//先来个有问题的代码
window.onscroll=function(){
console.log(new Date());
}
控制台会打印:
VM109:2 Sun Mar 12 2017 18:05:50 GMT+0800 (中国标准时间)
VM109:2 Sun Mar 12 2017 18:05:50 GMT+0800 (中国标准时间)
VM109:2 Sun Mar 12 2017 18:05:50 GMT+0800 (中国标准时间)
VM109:2 Sun Mar 12 2017 18:05:50 GMT+0800 (中国标准时间)
VM109:2 Sun Mar 12 2017 18:05:50 GMT+0800 (中国标准时间)
VM109:2 Sun Mar 12 2017 18:05:50 GMT+0800 (中国标准时间)
...
控制台会一直这样输入,那问题来了,这获取并不是我们想要的,我们并不想让他一直触发下去。
我们要解决这些问题,所以直接看代码:
//我们先来个节流,每秒输出一次
window.onscroll=function(){
if(window.onScrollTag == undefined){
window.onScrollTag=true;
console.log(new Date());
setTimeout(function(){
window.onScrollTag=undefined;
},1000);
}
}//先触发
window.onscroll=function(){
if(window.onScrollTag == undefined){
window.onScrollTag=setTimeout(function(){
window.onScrollTag=undefined;
console.log(new Date());
},1000); }
}//后触发
//从上面的代码可以看出来,我们在一个事件执行的时候就把标记改成不可用。一秒后才可以再次触发操作。
//我们在尝试一下去抖
window.onscroll=function(){
if(window.onScrollTag != undefined){
clearTimeout(window.onScrollTag);
}
window.onScrollTag=setTimeout(function(){
console.log(new Date());
},1000);
}//消抖,消除抖动,感觉这个更好听
//节流
funtion throttle(func, wait) {
var lastTime = 0,
timeout;
return funtion() {
var context = this,
args = arguments,
delay = wait || 100,
now = new Date().getTime();
if (now - lastTime <= delay) {
return;
}
lastTime = now;
clearTimeout(timeout);
timeout = setTimeout(function() {
timeout = null;
func.apply(context, args);
}, delay)
}
}
// 去抖
function debounce(func, wait) {
var timeout;
return function() {
var context = this,
args = arguments,
delay = wait || 250;
clearTimeout(timeout);
timeout = setTimeout(function() {
timeout = null;
func.apply(context, args);
}, delay);
};
}
throttle 应用场景
函数节流有哪些应用场景?哪些时候我们需要间隔一定时间触发回调来控制函数调用频率?
- DOM 元素的拖拽功能实现(mousemove)
- 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
- 计算鼠标移动的距离(mousemove)
- Canvas 模拟画板功能(mousemove)
- 搜索联想(keyup)
- 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次
debounce 应用场景
函数去抖有哪些应用场景?哪些时候对于连续的事件响应我们只需要执行一次回调?
- 每次 resize/scroll 触发统计事件
- 文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)
小结
函数节流和函数去抖的核心其实就是限制某一个方法被频繁触发,而一个方法之所以会被频繁触发,大多数情况下是因为 DOM 事件的监听回调,而这也是函数节流以及去抖多数情况下的应用场景
如果大家感兴趣,可以参考下:http://underscorejs.org/
javascript中的函数节流和函数去抖的更多相关文章
- JavaScript 中函数节流和函数去抖的讲解
JavaScript 中函数节流和函数去抖的讲解 我们都知道频繁触发执行一段js逻辑代码对性能会有很大的影响,尤其是在做一些效果实现方面,或者逻辑中需要进行后端请求,更是会导致卡顿,效果失效等结果,所 ...
- JavaScript 函数节流和函数去抖应用场景辨析
概述 也是好久没更新 源码解读,看着房价蹭蹭暴涨,心里也是五味杂陈,对未来充满恐惧和迷茫 ...(敢问一句你们上岸了吗) 言归正传,今天要介绍的是 underscore 中两个重要的方法,函数节流和函 ...
- 【javascript】js中的函数节流和函数防抖
一.概念解释 函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段. 大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...
- 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖
前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...
- javaScript函数节流与函数防抖
javaScript函数节流与防抖之区别 函数防抖(debounce)与函数节流(throttle)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟.假死或卡顿 ...
- JavaScript中常见的数组操作函数及用法
JavaScript中常见的数组操作函数及用法 昨天写了个帖子,汇总了下常见的JavaScript中的字符串操作函数及用法.今天正好有时间,也去把JavaScript中常见的数组操作函数及用法总结一下 ...
- JavaScript中常见的字符串操作函数及用法
JavaScript中常见的字符串操作函数及用法 最近几次参加前端实习生招聘的笔试,发现很多笔试题都会考到字符串的处理,比方说去哪儿网笔试题.淘宝的笔试题等.如果你经常参加笔试或者也是一个过来人,相信 ...
- js 函数节流throttle 函数去抖debounce
1.函数节流throttle 通俗解释: 假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯: 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟: ...
- 一篇文章把你带入到JavaScript中的闭包与高级函数
在JavaScript中,函数是一等公民.JavaScript是一门面向对象的编程语言,但是同时也有很多函数式编程的特性,如Lambda表达式,闭包,高阶函数等,函数式编程时一种编程范式. funct ...
随机推荐
- Python规范
1.命名 Django文件命名 小写+下划线 类:驼峰 2.edit 执行环境 work direction 到当前项目目录 3.类要加注释 4.去数据库找数据时需要try捕获异常,防止数据库连接断掉 ...
- Mac环境下Vagrant的安装
1.安装Vagrant 下载地址:https://www.vagrantup.com/downloads.html 下载好pkg包后,点击安装即可. 2.安装 VirtualBox 下载地址:http ...
- 【转】Python3—UnicodeEncodeError 'ascii' codec can't encode characters in position 0-1
转自:https://blog.csdn.net/AckClinkz/article/details/78538462 环境 >>> import sys >>> ...
- Linux input系统数据上报流程【转】
转自:https://segmentfault.com/a/1190000017255939 作为鸡生蛋系列文章,这里主要关注Linux input系统,主要为触摸事件上报流程. 读该文章最好有对li ...
- .Net业务搭配实用技术栈(转)
前言 昨天有篇文章在讨论webform的设计思路,我已经四五年不用webform了,虽然它也提供了HttpModule和httphandle来处理请求,提供了一般处理程序ashx来简化处理流程,但 ...
- expect 批量自动部署ssh 免密登陆
[root@node2 ssh]# cat auto_ssh.sh #!/usr/bin/expect -f ########################################## #通 ...
- eclpse:安装explorer或eExplorer插件
结论:个人感觉 eExplorer更好. 1.安装explorer Help->Eclipse Marketpalce find:explorer dian 点击"Install&qu ...
- uitramon 安装包
链接地址 密码:kkkk displayfintion :https://blog.csdn.net/JianJuly/article/details/80559933 密码:gn8p
- C语言--第0份作业
对网络专业的了解 •网络专业是现如今比较难学的科目,要学习利用计算机对网络进行管理开发. •网络专业对于思维的要求比较高,需要我们有一定的数学思维. •网络专业的人才比较缺失,只要我们学的足够 ...
- 01-Linux操作系统+指令
一.Linux操作系统 操作系统定义:操作系统直接运行在计算机上的系统软件, 它是与硬件打交道和控制软件运行的计算机程序. 虚拟机:就是模拟一个真实的计算机,好比一个虚拟的电 ...