摘要:节流的实现方式有两种主流的实现方式,一种是时间戳,一种是设置定时器。使用定时器有个问题就是点击不会立即执行,需要延迟设定的时间才会执行。
前言
在活动需求中,因为做的狂点小游戏。在实际体验中就会出现,频繁的点击造成动画的不连贯,影响用户体验。并且再播放音效的时候,如果没点击一次就触发一次音效会造成将声音压入到栈中,会持续的播放。因此在这里的操作做了节流的限制,隔多少秒触发一次。总结一下节流的实现方法。
节流节流的原理很简单:如果你持续触发事件,每隔一段时间,只执行一次事件。
根据首次是否执行以及结束后是否执行,效果有所不同,实现的方式也有所不同。
节流的实现方式有两种主流的实现方式,一种是时间戳,一种是设置定时器。
本次活动利用的就是该实现方式。
使用时间戳,当触发事件的时候,我们取出当前的时间戳,然后减去之前的时间戳(最一开始值设为0),如果大于设置的时间周期,就执行函数,然后更新时间戳为当前的时间戳,如果小于就不执行。
具体代码如下:
function throttle(fun, wait) { var context,args; var previous = 0; return function () { var now = +new Date();//格式化时间 context = this; args = arguments; if(now - previous > wait){ fun.apply(context,args); previous = now; } } }
如果在事件的回调中执行,就要具体修改一下。这样写法适用于,将要执行的函数直接赋值给事件。btn.addEventListener("click",throttle(addSelf,2000),false);因为throttle返回的是一个函数,直接赋值给事件可以触发执行。
var previous = 0; function throttle(fun, wait) { var context,args; return function () { var now = +new Date();//格式化时间 context = this; args = arguments; if(now - previous > wait){ fun.apply(context,args); previous = now; } } }
将previous提升到外面,写法就改为btn.addEventListener("click",function () {
throttle(addSelf,2000)(); },false); 这时throttle函数在后面要加小括号直接执行。使用定时器
当触发事件的时候,我们设置一个定时器,再触发事件的时候,如果定时器存在,就不执行,直到定时器执行,然后执行函数,清空定时器,这样就可以设置下个定时器。
function throttle(fun, wait) { var timeout context,args; return function () { context = this; args = arguments; if(!timeout){ timeout = setTimeout(function () { timeout = null; fun.apply(context,args) },wait) } } }
比较同理如果用在回调函数中,需要将timeout提到函数外面。
使用定时器有个问题就是点击不会立即执行,需要延迟设定的时间才会执行。
1.第一种事件会立即执行,第二种事件会在n秒后第一次执行
2.第一种事件停止触发后没有办法再执行事件,第二种事件停止触发后依然会再执行一次事件
结合这两种方法,并且可以配置是否要第一次立即执行或者停止触发后再执行一次。直接上代码
配置第三个参数leading:false表明不需要第一次立即执行。trailing:false表明停止触发后不再执行最后一次。
var previous = 0; var timeout; function throttle(fun, wait, options) { var context,args; /*var previous = 0;*/ if(!options) options = {}; var later = function () { previous = options.leading === false ? 0 :new Date().getTime(); timeout = null; fun.apply(context,args); if(!timeout) context = args = null; }; var throttled = function () { var now = new Date().getTime(); if(!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if(remaining <= 0 || remaining > wait) { if(timeout){ clearTimeout(timeout); timeout = null; } previous = now; fun.apply(context,args); if(!timeout) context = args = null; } else if(!timeout && options.trailing !==false){ timeout = setTimeout(later,remaining) } }; return throttled; } //使用 btn.addEventListener("click",function () { throttle(addSelf,2000,{trailing:false})(); },false);
注意默认情况下都是兼顾了第一次点击立即触发和最后触发后执行一次。
leading:false和trailing:false不能同时设置。
如果同时设置的话,比如当你在不再点击的时候,因为trailing设为了false,停止触发不会设置定时器,所以只要再过了设置的时间,在点击的话,就会立即执行,就违反了leading:false了。所以该方法只有三种情况可用。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/90045.html
摘要:函数节流的原理函数节流的原理挺简单的,估计大家都想到了,那就是定时器。在高级程序设计一书有介绍函数节流,里面封装了这样一个函数节流函数,它把定时器存为函数的一个属性个人的世界观不喜欢这种写法。 什么是函数节流? 介绍前,先说下背景。在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱...
摘要:为了解决这些问题,就可以使用定时器对函数进行节流。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。 函数节流的目的 从字面上就可以理解,函数节流就是用来节流函数从而一定程度上优化性能的。例如,DOM 操作比起非DOM 交互需要更多的内存和CPU 时间。连续尝试进行过多的DOM 相关操作可能会导致浏览器挂起,有时候甚...
摘要:目的都是为了降低回调函数执行频率,节省计算机资源,优化性能,提升用户体验。函数防抖事件频繁触发的情况下,只有经过足够的空闲时间,才执行代码一次。 函数节流和函数防抖的对比分析 一、前言 前端开发中,函数节流(throttle) 和 函数防抖(debounce) 作为常用的性能优化方法,两者都是用于优化高频率执行 js 代码的手段,那具体它们有什么异同点呢?有对这两个概念不太了解的小伙伴...
摘要:此时需要采用防抖和节流的方式来减少调用频率,同时不影响原来效果。函数防抖当持续触发事件时,一段时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前就触发了事件,延时重新开始。 js 防抖 节流 JavaScript 实际工作中,通过监听某些事件,如scroll事件检测滚动位置,根据滚动位置显示返回顶部按钮;如resize事件,对某些自适应页面调整DOM的渲染;如ke...
摘要:主要实现思路就是通过定时器,通过设置延时时间,在第一次调用时,创建定时器,写入需要执行的函数。如果这时前一个定时器暂未执行,则将其替换为新的定时器。 JS中的函数节流 一、什么是函数节流(throttle) 概念:限制一个函数在一定时间内只能执行一次。 举个栗子,坐火车或地铁,过安检的时候,在一定时间(例如10秒)内,只允许一个乘客通过安检入口,以配合安检人员完成安检工作。上例中,每1...
阅读 3404·2021-11-19 09:40
阅读 1297·2021-10-11 11:07
阅读 4806·2021-09-22 15:07
阅读 2871·2021-09-02 15:15
阅读 1947·2019-08-30 15:55
阅读 518·2019-08-30 15:43
阅读 863·2019-08-30 11:13
阅读 1430·2019-08-29 15:36