jQuery动画计数器优化:从当前值续增至目标值而非重置
问题
编写了如下jQuery计数器动画函数,可正常运行。但点击按钮将.set的数值设置为30并重新调用计数器函数时,计数器会从0开始动画到30。需要实现从当前的25状态续增至30,而非重置计数器。
原代码:
JavaScript代码
$.fn.counter = function(){ var $el = this; $el.prop('Counter',0).animate({ Counter: $el.text() }, { duration: 4000, easing: 'swing', step: function (now) { $el.text(Math.ceil(now)); } }); }; $(".set").counter(); $('#add').on('click', function(e) { $(".set").text(30); $(".set").counter(); });
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="set">25</div> <button id="add">Add to 30</button>
最优实现方案
核心问题是每次调用counter函数时,都强制把Counter属性重置为0,导致动画从0开始。要实现续增,需保留当前的动画进度值作为起始点,同时避免提前修改元素文本打断动画流程。
修改思路
- 给计数器函数添加目标值参数,避免直接修改元素文本覆盖当前显示的数值。
- 动画起始值读取当前
Counter属性的实时值(首次运行则取元素初始文本),而非固定设为0。 - 触发续增时,直接传入目标数值,让动画从当前值平滑过渡到目标值。
修改后的完整代码
JavaScript代码
$.fn.counter = function(targetVal){ var $el = this; // 获取当前Counter的实时值,首次运行则取元素初始文本转数字 var currentVal = parseFloat($el.prop('Counter')) || parseFloat($el.text()); // 未传入目标值时,默认使用元素当前文本;传入则用目标值 targetVal = targetVal || parseFloat($el.text()); // 从当前值开始动画到目标值 $el.prop('Counter', currentVal).animate({ Counter: targetVal }, { duration: 4000, easing: 'swing', step: function (now) { $el.text(Math.ceil(now)); } }); }; // 初始化时不传参数,用元素初始文本25启动动画 $(".set").counter(); $('#add').on('click', function(e) { // 直接传入目标值30,无需提前修改元素文本 $(".set").counter(30); });
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="set">25</div> <button id="add">Add to 30</button>
关键改动说明
- 新增
targetVal参数,用于接收目标数值,避免提前修改元素文本打断动画进程。 - 动画起始值改为读取当前
Counter属性的实时值(动画过程中该值会随step方法更新),首次运行时 fallback 到元素初始文本值。 - 点击按钮时不再修改元素文本,直接传入目标值30调用计数器函数,动画会从当前显示的数值(无论是初始25还是动画中的中间值)平滑过渡到30。
内容的提问来源于stack exchange,提问作者HiDayurie Dave
相关产品推荐
相关产品推荐

