如何在HTML中实现数字滚动跳动(Tick Up)动画效果
实现数字滚动跳动(Tick Up)计数器效果
我想实现数字变化时的「滚动跳动(Tick Up)」效果,类似Twitter的点赞/转发/评论计数器以及Discord的反应计数器。原代码存在问题:新数字会显示在原数字旁边,向上滚动后只保留新数字向下回到原位,我想要的效果是新数字位于旧数字下方,动画结束后直接恢复到初始位置。
原代码问题分析
原JS代码里的_x.innerHTML += _x.innerHTML + "<br>" + num是核心错误——这会把当前计数器的内容重复一遍,再追加新数字,导致旧数字、重复的旧数字、新数字挤在一起,完全不符合“旧数字在上,新数字在下”的预期结构。
修正后的完整代码
HTML
<span id="counter" class="counter">0</span> <button onclick="changeCounter('counter', Math.floor(Math.random()*100))">切换数字</button>
CSS
.counter { display: inline-block; height: 15px; font-size: 15px; line-height: 15px; /* 保证文字垂直居中,每行高度和容器一致 */ overflow-y: hidden; transition: margin-top 0.2s ease; /* 把过渡效果写在CSS里,简化JS逻辑 */ }
JavaScript
function changeCounter(id, num) { const counter = document.getElementById(id); const oldValue = counter.textContent; // 用textContent获取纯文本,避免HTML干扰 // 构建旧值在上、新值在下的结构 counter.innerHTML = `${oldValue}<br>${num}`; // 等待DOM更新后触发滚动动画(16ms约为一帧时间) setTimeout(() => { counter.style.marginTop = "-15px"; }, 16); // 动画结束后重置状态,为下一次动画做准备 setTimeout(() => { counter.textContent = num; counter.style.marginTop = "0"; }, 220); // 0.2s动画时长 + 16ms延迟,确保动画完全结束后再重置 }
关键修改说明
- 结构修正:不再重复旧内容,直接用
<br>分隔旧值和新值,形成标准的上下两行布局,新数字自然处于旧数字下方。 - CSS优化:添加
line-height消除滚动时的文字偏移,把过渡效果固化在CSS中,不用每次通过JS动态设置。 - JS逻辑调整:
- 用
textContent读取旧值,避免HTML元素干扰; - 延迟16ms触发滚动,确保浏览器完成上下结构渲染后再执行动画;
- 动画结束后直接重置为新数字并归位
margin-top,保证下一次动画的初始状态正确。
- 用
内容的提问来源于stack exchange,提问作者wutadam
相关产品推荐
相关产品推荐

