您的位置:首页 > Web前端 > JQuery

利用原生JS与jQuery实现数字线性变化的动画

2017-02-24 09:46 946 查看

大家应该都有所体会,在一些数据展示的专题页里,有时候希望数字能动态从某一个数变化到另一个数,以此来吸引用户眼球,突出数据。于是有了下文。

在这里,我用了两种方式:一种是原生的JavaScript,另一种是jQuery插件。

数字线性变化的原理很简单,就是让数字增量变化,并循环动画。

原生JS版

首先获取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插件版

原理同上,只是DOM元素获取使用jQuery方法,并把数字动画方法封装成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>

最后

好了,以上就是这篇文章的全部内容了,后期会考虑加上缓动函数的选择项。希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

您可能感兴趣的文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息