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


Posted in Javascript onFebruary 24, 2017

前言

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

在这里,我用了两种方式:一种是原生的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>

最后

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

Javascript 相关文章推荐
一个简单的js动画效果代码
Jul 20 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
Feb 12 Javascript
jQuery中ajax的load()方法用法实例
Dec 26 Javascript
ajax读取数据后使用jqchart显示图表的方法
Jun 10 Javascript
JavaScript-html标题滚动效果的简单实现
Sep 08 Javascript
Bootstrap基本模板的使用和理解1
Dec 14 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
Jan 19 Javascript
老生常谈jacascript DOM节点获取
Apr 17 Javascript
vue开发环境配置跨域的方法步骤
Jan 16 Javascript
小程序实现分类页
Jul 12 Javascript
微信小程序实现图片选择并预览功能
Jul 25 Javascript
jquery实现点击弹出对话框
Feb 08 jQuery
JavaScript和jQuery制作光棒效果
Feb 24 #Javascript
微信小程序 动态的设置图片的高度和宽度详解及实例代码
Feb 24 #Javascript
微信小程序实现实时圆形进度条的方法示例
Feb 24 #Javascript
JavaScript中三种常见的排序方法
Feb 24 #Javascript
Angular2 Service实现简单音乐播放器服务
Feb 24 #Javascript
Bootstrap3多级下拉菜单
Feb 24 #Javascript
使用原生的javascript来实现轮播图
Feb 24 #Javascript
You might like
咖啡的化学
2021/03/03 咖啡文化
PHP简单读取xml文件的方法示例
2017/04/20 PHP
PHP实现的猴王算法(猴子选大王)示例
2018/04/30 PHP
javascript实现 在光标处插入指定内容
2007/05/25 Javascript
得到form下的所有的input的js代码
2013/11/07 Javascript
javascript回车完美实现tab切换功能
2014/03/13 Javascript
Js冒泡事件详解及阻止示例
2014/03/21 Javascript
node.js中的events.emitter.removeAllListeners方法使用说明
2014/12/10 Javascript
setinterval()与clearInterval()JS函数的调用方法
2015/01/21 Javascript
jQuery操作cookie
2016/08/08 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
2017/06/30 Javascript
前端主流框架vue学习笔记第二篇
2017/07/26 Javascript
利用jqprint插件打印页面内容的实现方法
2018/01/09 Javascript
如何在vue里面优雅的解决跨域(路由冲突问题)
2019/01/20 Javascript
vue项目中使用scss的方法步骤
2019/05/16 Javascript
如何在面试中手写出javascript节流和防抖函数
2020/10/22 Javascript
使用C语言来扩展Python程序和Zope服务器的教程
2015/04/14 Python
Python的MongoDB模块PyMongo操作方法集锦
2016/01/05 Python
浅谈插入排序算法在Python程序中的实现及简单改进
2016/05/04 Python
Python的requests网络编程包使用教程
2016/07/11 Python
Python如何为图片添加水印
2016/11/25 Python
对pandas的dataframe绘图并保存的实现方法
2017/08/05 Python
Python实现矩阵转置的方法分析
2017/11/24 Python
Python 3.7新功能之dataclass装饰器详解
2018/04/21 Python
python交换两个变量的值方法
2019/01/12 Python
Python实现将字符串的首字母变为大写,其余都变为小写的方法
2019/06/11 Python
Python绘制堆叠柱状图的实例
2019/07/09 Python
python默认参数调用方法解析
2020/02/09 Python
CSS3等相关属性制作分页导航实现代码
2012/12/24 HTML / CSS
CSS3 实现的缩略图悬停效果
2020/12/09 HTML / CSS
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
日本即尚网:JSHOPPERS.com(支持中文)
2019/12/03 全球购物
幼师辞职信怎么写
2015/02/27 职场文书
停发工资证明范本
2015/06/12 职场文书
2015年新农村建设指导员工作总结
2015/07/24 职场文书
教师个人工作总结范文2015
2015/10/14 职场文书