原生JS与jQuery实现数字线性递增动画
作者:像素漫游时间:2026-10-22 01:15:21浏览:249
本文介绍如何使用原生JavaScript和jQuery插件实现数字从起始值到结束值的线性递增动画。通过封装DOM获取与定时器逻辑,提供兼容IE6的解决方案及jQuery扩展方法,适用于数据展示场景。
前言
前言
在许多数据展示页面中,为了吸引用户注意力并突出关键数据,常需让数字动态从初始值变化至目标值。
本文提供两种实现方案:原生JavaScript与jQuery插件。
数字线性变化的核心原理是计算增量并循环执行动画。
原生JavaScript实现
原生JavaScript实现
首先需获取DOM元素。为兼容IE6等旧版浏览器,采用以下兼容性获取方法:
var domUtil = {
// 获取DOM元素
get: function(query) {
var _this = this;
if(document.querySelector) {
return document.querySelector(query);
} else {
var elements = document;
var queryStrArray = query.split(/ +/);
for(var i = 0; i < queryStrArray.length; i++) {
var domName = queryStrArray[i];
elements = _this.getElementsOfParentNode(domName, elements);
}
if(elements.length == 1) {
return elements[0];
} else {
return elements;
}
}
},
// 获取DOM元素
getElementsOfParentNode: function(domName, parentNode) {
var _this = this;
parentNode = parentNode || document;
domName = domName.trim();
var regExps = {
id: /^#/,
class: /^/
};
if(regExps.id.test(domName)) {
domName = domName.replace(/^\#/g, "");
return parentNode.getElementById(domName);
} else if(regExps.class.test(domName)) {
domName = domName.replace(/^./g, "");
return _this.getElementsByClassName(domName, parentNode);
} else {
return parentNode.getElementsByTagName(domName);
}
},
// 获取class元素的兼容方法
getElementsByClassName: function(className, parentNode) {
if(parentNode.getElementsByClassName){
return parentNode.getElementsByClassName(className);
} else {
className = className.replace(/^ +| +$/g,"");
var classArray = className.split(/ +/);
var eles = parentNode.getElementsByTagName("*");
for(var i = 0;i < classArray.length; i++){
var classEles = [];
var reg = new RegExp("(^| )" + classArray[i] + "( |$)");
for(var j = 0;j < eles.length; j++){
var ele = eles[j];
if(reg.test(ele.className)){
classEles.push(ele);
}
}
eles = classEles;
}
return eles;
}
}
};
/*
* 数字动画(目前仅支持数字动画的线性变化)
* options参数:
* element {String} DOM元素query字符串
* from {Number} 起始数字
* to {Number} 终点数字
* duration {Number} 动画时间
* callback {Function} 数字变化时的回调函数
*/
var animatingNumber = function(options) {
this.element = domUtil.get(options.element);
this.startNum = options.from;
this.endNum = options.to;
this.duration = options.duration || 2000;
this.callback = options.callback;
this.timer = null;
};
animatingNumber.prototype = {
start: function() {
var _this = this;
_this.animate();
},
stop: function() {
if(this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
},
animate: function() {
var _this = this;
var curNum = _this.startNum;
var animateTime = 0;
var range = _this.endNum - _this.startNum;
var timerStep = Math.abs( Math.floor(_this.duration / range) );
timerStep = timerStep > 20 ? timerStep : 20;
var numStep = (range / _this.duration) * timerStep;
_this.stop();
(function animate() {
_this.timer = setTimeout(function() {
curNum = Math.ceil( curNum + numStep );
if( (_this.endNum > _this.startNum && curNum >= _this.endNum) || (_this.endNum < _this.startNum && curNum <= _this.endNum) ) {
curNum = _this.endNum;
}
_this.element.innerText = curNum;
animateTime++;
if(typeof this.callback == 'function') {
this.callback(curNum);
}
animate();
if(curNum >= _this.endNum) {
_this.stop();
}
}, timerStep);
})();
}
};
animatingNumber.create = function(options) {
return new animatingNumber(options);
};
使用示例如下:
<p>Number: <span class='dynamicNum'>500</span></p>
<script>
animatingNumber.create({
element: '.dynamicNum',
from: 1,
to: 500,
duration: 2000
}).start();
</script>
jQuery插件实现
jQuery插件实现
原理与原生版一致,区别在于利用jQuery获取DOM元素,并将数字动画逻辑封装为jQuery插件。
插件代码如下:
/*
* 数字动画(目前仅支持数字动画的线性变化)
* options参数:
* from {Number} 起始数字
* to {Number} 终点数字
* duration {Number} 动画时间
* callback {Function} 数字变化时的回调函数
*/
(function( $ ) {
$.fn.animatingNumber = function(options) {
var settings = {
element: this,
startNum: options.from,
endNum: options.to,
duration: options.duration || 2000,
callback: options.callback
};
var timer = null;
var methods = {
start: function() {
var _this = this;
_this.animate();
},
stop: function() {
if(timer) {
clearTimeout(timer);
timer = null;
}
},
animate: function() {
var _this = this;
var curNum = settings.startNum;
var animateTime = 0;
var range = settings.endNum - settings.startNum;
var timerStep = Math.abs( Math.floor(settings.duration / range) );
timerStep = timerStep > 20 ? timerStep : 20;
var numStep = (range / settings.duration) * timerStep;
_this.stop();
(function animate() {
timer = setTimeout(function() {
curNum = Math.ceil( curNum + numStep );
if( (settings.endNum > settings.startNum && curNum >= settings.endNum) || (settings.endNum < settings.startNum && curNum <= settings.endNum) ) {
curNum = settings.endNum;
}
settings.element.text(curNum);
animateTime++;
if(typeof settings.callback == 'function') {
settings.callback(curNum);
}
animate();
if(curNum >= settings.endNum) {
_this.stop();
}
}, timerStep);
})();
}
};
return this.each(function() {
return methods.start();
});
};
})( jQuery );
调用示例如下:
<p>Number: <span class='dynamicNum'></span></p>
<script>
$('.dynamicNum').animatingNumber({
from: 1,
to: 1000,
duration: 2000
});
</script>
总结
总结
以上内容为本文全部要点。后续计划增加缓动函数选项。希望本文对您的学习或工作有所帮助,如有疑问欢迎留言交流。
作者最新文章
D3.js 处理大规模数据点的性能优化策略
2026-11-05 15:37:25
JS实现网页摄像头实时扫码:结合getUserMedia与jsQR教程
2026-11-05 15:27:28
D3.js v5 迁移到 v7 的 API 变更与注意事项
2026-11-05 11:57:17
使用 animate.js 实现多元素协同的序列动画
2026-11-04 22:27:53
JS拖拽排序时怎么添加平滑动画效果?FLIP技术实战
2026-11-04 10:12:22
