欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-08-16 16:58:14
前言 大家应该都有所体会,在一些数据展示的专题页里,有时候希望数字能动态从某一个数变化到另一个数,以此来吸引用户眼球,突出数据。于是有了下文。 在这里,我用了两种方式:...

前言

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

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

最后

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