关于做常规的数字定时滚动效果
栏目: JavaScript · 发布时间: 6年前
内容简介:目前项目团队在做一个接受到的数字要做成实现数字滚动效果 在轮询的基础上做的 就是上一个数字到目前最新的数字的变化 我想到的就是用使用setTimeout定时器那么写到这里是不是就可以简单实现了呢 其实还有一段路要走,比如你考虑了性能问题了吗上一步我们增加了防抖就是在递归调用当上一个setTimeout还存在的时候 我们要清除掉setTimeout 以免造成干扰和卡顿现象 那么是不是就可以了呢 你考虑过1秒之内setTimeout也有极限的吗 根据各个浏览器的性能差异,应该控制在20ms~30ms之间,那
目前项目团队在做一个接受到的数字要做成实现数字滚动效果 在轮询的基础上做的 就是上一个数字到目前最新的数字的变化 我想到的就是用使用setTimeout定时器
/** * 定时器方法 * @param num {number} 当前值 * @param digitalBeating {number} 上一个值 * @param diff {number} num - digitalBeating的差值 */ transNum(num,digitalBeating,diff) { let i = digitalBeating,timeout = null; const animate = () => { if (i<num) { i++ timeout = setTimeout(animate,1000/diff) } else { digitalBeating = num } let numList = i.toString().split('') // 这里是为了以数组的形式单独展示每一个数字 } animate() } 复制代码
那么写到这里是不是就可以简单实现了呢 其实还有一段路要走,比如你考虑了性能问题了吗
transNum(num,digitalBeating,diff) { let i = digitalBeating,timeout = null; const animate = () => { if (timeout) { clearTimeout(timeout) timeout = null } if (i<num) { i++ timeout = setTimeout(animate,1000/diff) } else { digitalBeating = num } let numList = i.toString().split('') // 这里是为了以数组的形式单独展示每一个数字 } animate() } 复制代码
上一步我们增加了防抖就是在递归调用当上一个setTimeout还存在的时候 我们要清除掉setTimeout 以免造成干扰和卡顿现象 那么是不是就可以了呢 你考虑过1秒之内setTimeout也有极限的吗 根据各个浏览器的性能差异,应该控制在20ms~30ms之间,那么我们进行下一步的改造
transNum(num,digitalBeating,diff) { let i = digitalBeating,timeout = null,steps = 1; const animate = () => { if (timeout) { clearTimeout(timeout) timeout = null } if (i<num) { if(diff<=50) { steps = 1 } else if (diff=<100&&diff>50) { steps = 2 } else if (diff>100&&diff<150) { steps = 3 } else if ... i += steps timeout = setTimeout(animate,1000*steps/diff) } else { digitalBeating = num } let numList = i.toString().split('') // 这里是为了以数组的形式单独展示每一个数字 } animate() } 复制代码
我们定义了一个变量steps作为步长来保证1秒之内调用的次数,可是以上的行为会不会很蠢 因为你没办法知道这个diff差值到底是多少 没有封顶的 所以我们继续改造
transNum(num,digitalBeating,diff) { let i = digitalBeating,timeout = null,len = diff.toString().length,steps = Math.pow(10,len-2); const animate = () => { if (timeout) { clearTimeout(timeout) timeout = null } if (i<num) { if(diff<10) { steps = 1 } if (diff/steps>50) { steps *= 2 } i += steps timeout = setTimeout(animate,1000*steps/diff) } else { digitalBeating = num } let numList = i.toString().split('') // 这里是为了以数组的形式单独展示每一个数字 } animate() } 复制代码
目前来看大概就可以保证在1秒之内调用次数50次了,不过呢,你可能会发现最后一次的数字变动可能是i>num了 那么肯定就不是我们想要的结果了,就在最后一次再加个判断吧
transNum(num,digitalBeating,diff) { let i = digitalBeating,timeout = null,len = diff.toString().length,steps = Math.pow(10,len-2); const animate = () => { if (timeout) { clearTimeout(timeout) timeout = null } if (i<num) { if(diff<10) { steps = 1 } if (diff/steps>50) { steps *= 2 } i += steps timeout = setTimeout(animate,1000*steps/diff) // 这里作为最后一次判断 如果最后一次的i和num的差距小于steps时 肯定会跳过了 if (num-i<steps) { i = num } } else { digitalBeating = num } let numList = i.toString().split('') // 这里是为了以数组的形式单独展示每一个数字 } animate() } 复制代码
再来看看 是不是基本上能满足需求了呢 那么你能保证不会延迟吗 所以应该规定在1秒之内必须跑完了
transNum(num,digitalBeating,diff) { let i = digitalBeating, timeout = null, len = diff.toString().length, steps = Math.pow(10,len-2) _lastTime = new Date(); // 设置初始时间 const animate = () => { if (timeout) { clearTimeout(timeout) timeout = null } let _nowTime = new Date() // 这一轮调用时的时间 // 在这里统一判断 if (i<num && num-i>=steps && _nowTime - _lastTime<1000) { if(diff<10) { steps = 1 } if (diff/steps>50) { steps *= 2 } i += steps timeout = setTimeout(animate,1000*steps/diff) } else { i = num clearTimeout(timeout) timeout = null digitalBeating = num } let numList = i.toString().split('') // 这里是为了以数组的形式单独展示每一个数字 } animate() } 复制代码
唔,现在也许可行了吧 然而做了这么多 其实还是不够完美的 一个是数字滚动就不是一个数字一个数字的滚了 而且用了定时器了 这个本身就是耗费性能的事 有没有更优的办法呢 当然有 请期待用css transition 3d来实现
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 单机服务器部署Nginx/Node/Nuxt/React/NG,常规优化,常规自启脚本
- Rust 入坑指南:常规套路
- 三分钟快速搞定 Git 常规使用
- 三分钟快速搞定 Git 常规使用
- layui 2.2.5 发布,常规更新
- RabbitMQ 3.7.4 发布,常规更新
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。