js的节流和防抖
1,节流
节流就是对连续的函数触发,在设定的间隔时间段内,只让其执行一次。
先来看看js高级程序设计3里面节流的代码
- function throttle (method, context, wait) {
- clearTimeout(method.tId)
- method.tId = setTimeout(function () {
- method.call(context)
- }, wait)
- }
当函数连续执行的时候,如果之前的定时器还没执行,就把它清除了,再从新设置一个新的定时器。
我们可以对这个进行改进
- function throttle (fn, wait) {
let timeout;
let prevTime = 0;
return function(...args) { //返回一个函数
let now = new Date();
let remaining = wait - (now - prevTime) // 下一次执行的时间,
if (remaining <=0 || remaining > wait) { // 如果下一次的时间小于等于0,立刻执行一次函数,并把时间戳改为当前的时间。
clearTimeout(timeout)
timeout = null
prevTime = now
fn.apply(this, args)
} else if (!timeout) { // 如果当前没有定时器 那么就新加一个定时器。
timeout = setTimeout(() => {
timeout = null;
prevTime = new Date();
fn.apply(this, args)
}, remaining)
}
}
}
第一次执行: timeout为undefined, prevTime为0 remaining为负数,走if的第一个,立即执行了函数并将下次时间改成当前时间
第二次执行: 下一次时间为正,定时器还是为undefined,走if的第二个,设置定时器
下一次执行(不超过wait时间内) : remaining大于0,定时器为true,所以直接跳出
understore里面的节流考虑了两个高级的配置: 是否在第一次触发的时候就执行函数 和 最后一次的定时器触发的执行函数。还提供了节流的取消函数。
- function throttle(fn, wait, option = {}) {
- let timeout;
- let prevTime = 0
- let throttled = function(...args){
- let now = new Date();
- if (!prevTime && option.leading === false) prevTime = now;
- let remaining = wait - (now - prevTime);
- if (remaining <= 0 || remaining > wait) {
- if (timeout) {
- clearTimeout(timeout)
- timeout = null;
- }
- prevTime = now
- fn.apply(this, args)
- } else if (!timeout && option.trailing !== false) {
- timeout = setTimeout(() => {
- prevTime = option.leading === false ? 0 : new Date;
- fn.apply(this, args)
- })
- }
- }
- throttled.cancel = () => {
- clearTimeout(timeout);
- prevTime = 0;
- timeout = null;
- }
- return throttled
- }
除了加了两个配置项和取消函数,别的基本都是一样的。
需要注意的是,首次不执行和最后不执行这两个不能同时配置,只能配置一个。
2,防抖
其实我感觉防抖和节流差别不大,主要的差别在于: 在wait的时间内,反复触发函数的话,节流不会理会这些,而防抖的话,只要你触发了,他就会清除之前的定时器,从新设置一个定时器。
比如说坐电梯,如果是节流的话,电梯等待时间为5S,从第一个人进电梯开始算,到5S后他就会关门运行。
如果是防抖的话,电梯等待时间为5S,在这5S之内,如果有人进电梯,他就会重新计时,只有在5S中没有人进电梯了,电梯才关门运行。
- function debounce (fn, wait) {
let timeout;
return function(...args) {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, args)
}, wait)
}
}
返回一个函数, 先清除之前的定时器,然后再新加定时器。
underscore里面的防抖添加了一个高级配置,是否立即执行一次函数。
- function debounce(fn, wait, immediate) {
- let timeout;
- return function(...args) {
- let callNow = immediate && !timeout;
- if (timeout) clearTimeout(timeout);
- timeout = setTimeout(() => {
- timeout = null;
- if (!immediate) fn.apply(this, args)
- }, wait)
- if (callNow) fn.apply(this, args)
- }
- }
这里添加了immediate这个配置项,如果为true的话,那么触发第一次的时候就执行了要执行的函数,定时器里面不执行。
js的节流和防抖的更多相关文章
- js 函数节流和防抖
js 函数节流和防抖 throttle 节流 事件触发到结束后只执行一次. 应用场景 触发mousemove事件的时候, 如鼠标移动. 触发keyup事件的情况, 如搜索. 触发scroll事件的时候 ...
- JS 函数节流与防抖
前言 事件的触发权很多时候属于用户,可能会出现下列问题: 向后台发送数据,用户频繁触发,对服务器造成压力: 一些浏览器事件,如window.onresize,window.mousemove等,触发的 ...
- JS函数节流和防抖
看JS高级程序设计时,了解到一个概念--函数节流,是为了防止在高频率触发某些事件导致浏览器崩溃.最近又了解到另一个概念,防抖,感觉和函数节流很像,也查看了很多篇博文,算是理解了. 区别: 函数节流:频 ...
- JS的节流、防抖及使用场景
前言 据说阿里有一道面试题就是谈谈函数节流和函数防抖. 糟了,这可触碰到我的知识盲区了,好像听也没听过这2个东西,痛定思痛,赶紧学习学习.here we go! 概念和例子 函数防抖(debounce ...
- js函数节流和防抖的理解与实现
一:函数防抖1.理解:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间2.思路:每次触发事件时都取消之前的延时调用方法 3.实现: function debounce ...
- js的节流、防抖以及使用场景
介绍 首先看一个没有经过任何处理的: 1 // 模拟一个输出的函数 2 function input(value) { 3 console.log(`输入的内容${value}`) 4 } 5 con ...
- 7分钟理解JS的节流、防抖及使用场景
前言 据说阿里有一道面试题就是谈谈函数节流和函数防抖.糟了,这可触碰到我的知识盲区了,好像听也没听过这2个东西,痛定思痛,赶紧学习学习.here we go! 概念和例子 函数防抖(debounce) ...
- 一文理解JS的节流、防抖及使用场景
函数防抖(debounce):在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时. 看一个
- js函数的节流和防抖
js函数的节流和防抖 用户浏览页面时会不可避免的触发一些高频度触发事件(例如页面 scroll ,屏幕 resize,监听用户输入等),这些事件会频繁触发浏览器的重拍(reflow)和重绘(repai ...
随机推荐
- tp5 whereOr
题目:查询grade=1 or class=2 or sex=3的学生 $condition[; $condition[; $condition[; $list =Db::name($this-> ...
- 【原创】cython and python for kenlm
未经允许不可转载 Kenlm相关知识 Kenlm下载地址 kenlm中文版本训练语言模型 如何使用kenlm训练出来的模型C++版本 关于Kenlm模块的使用及C++源码说明 加载Kenlm模块命令 ...
- easyui-tabs扩展根据自定义属性打开页签
.增加扩展 <script type="text/javascript" > /** * @author {kexb} easyui-tab扩展根据id切换页面 */ ...
- SceneBuilder 打不开 .fxml文件,只在任务栏显示
mark一下,今天下载官网的SceneBuilder 2.X 最近在使用JavaFX,感觉还是很酷的,可是在正常的编辑关闭SceneBuilder 之后,再次打开却打不开了 可是奇怪的是有些 .fxm ...
- [GO]匿名字段的同名字段操作
package main import ( "fmt" ) type Person struct { name string sex byte age int } type Stu ...
- 自定义DropDownMenu菜单
在JayFang1993 / DropDownMenu的基础上进行修改,最后的到自己想要的效果 本来的效果: 而我最后实现的效果是: 我们先来分析一下DropDownMenu的源代码 需要改动的地方 ...
- AC620教程 第十五节 8位7段数码管驱动设计与验证
本章导读 电子系统中常用的显示设备有数码管.LCD液晶以及VGA显示器等.其中数码管又可分为段式显示(7段.米字型等)以及点阵显示(8*8.16*16等),LCD液晶的应用可以分为字符式液晶(1602 ...
- Gym - 101498G(Super Subarray )
In this problem, subarray is defined as non-empty sequence of consecutive elements. We define a suba ...
- Android-主题
主题分为两种: 第一种:使用Android系统提供的主题 第二种:自己定义主题 样式 与 主题 区分理解 样式是控制(View的子类风格)控件风格 或者 是(ViewGroup的子类风格)布局风 ...
- VMware下拷过来的Linux系统ifconfig下没有网络问题
拷了同事的Linux系统,拷过来时还可以用,今天再打开发现找不到ip了,于是就在网上找解决方法,因本人从没接触过Linux所以查的挺多的但解决的方法试了好几个就是不行,后面找到的有效的解决方法有: L ...