如何使用JavaScript制作你自己的countUp.js插件

  • Post category:jquery

制作自己的countUp.js插件需要以下步骤:

1. 插件的结构

首先我们需要构建插件的基本结构,可以选择通过函数或对象的方式来组织代码。然后需要定义countUp插件对象,其需要包括如下属性:

  • startVal: 开始计数的值;
  • endVal: 结束计数的值;
  • duration: 计数持续时间;
  • options: 自定义选项,包括前缀、后缀、小数点位数等等。

2. 实现计数

然后需要实现计数的方法,我们可以选择借助requestAnimationFrame来实现单次更新计数器的值。在计数完成之后,需要删除该计数节点。

3. 添加到DOM

最后需要把计数器添加到DOM中。我们可以选择创建一个新的DOM元素并插入到指定节点中。同时,在某些情况下,我们还可以完善计数器的一些表现形式,比如添加动画效果等等。

示例1:以函数的方式实现countUp.js插件

下面给出一个以函数的方式实现的countUp插件:

function countUp(el, startVal, endVal, duration, options) {
  var reqAnimationFrame =
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame;

  var startTime = null;
  var endTime = duration;
  var currentVal = startVal;
  var elem = document.getElementById(el);
  var decimalPlaces = isNaN(options.decimalPlaces = Math.abs(options.decimalPlaces)) ? 0 : options.decimalPlaces;
  var prefix = options.prefix !== undefined ? options.prefix : '';
  var suffix = options.suffix !== undefined ? options.suffix : '';

  var countTo = function (timestamp) {
    if (!startTime) startTime = timestamp;
    var currentTime = timestamp - startTime;
    var progress = currentTime / endTime;
    progress = progress > 1 ? 1 : progress;
    currentVal = startVal + (endVal - startVal) * countUpEasing(progress);
    currentVal = parseFloat(currentVal.toFixed(decimalPlaces));
    if (elem) elem.innerHTML = prefix + formatNumber(currentVal) + suffix;
    if (progress < 1) reqAnimationFrame(countTo);
  };

  reqAnimationFrame(countTo);
}

function countUpEasing(t) {
  return --t * t * t + 1;
}

function formatNumber(num) {
  num = num.toFixed(2);
  num = num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  return num;
}

在这个代码段中,我们定义了一个countUp函数,它的参数分别是:

  • el: DOM元素的id;
  • startVal: 开始计数的值;
  • endVal: 结束计数的值;
  • duration: 计数持续时间;
  • options: 自定义选项对象,包括前缀、后缀、小数点位数等等。

这个函数中主要工作是通过requestAnimationFrame方法来实现计数器的更新,并在计数结束之后删除计数节点。在更新计数器的时候,我们提供了一个countUpEasing函数来进行缓动运动。同时,我们还提供了一个格式化数字的函数formatNumber来添加千位分隔符并保留小数点位数。

示例2:以对象的方式实现countUp.js插件

下面给出一个以对象的方式实现的countUp插件:

function CountUp(options) {
  var _this = this;
  var reqAnimationFrame =
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame;

  var defaults = {
    el: null,
    startVal: 0,
    endVal: 100,
    duration: 1000,
    prefix: '',
    suffix: '',
    decimalPlaces: 0,
    easingFn: null,
    onComplete: null
  };

  var options = _extend(defaults, options);

  function _extend(objA, objB) {
    for (var key in objB) {
      if (objB.hasOwnProperty(key)) {
        objA[key] = objB[key];
      }
    }
    return objA;
  }

  _this.start = function () {
    var startTime = null;
    var endTime = options.duration;
    var currentVal = options.startVal;
    var elem = document.getElementById(options.el);
    var decimalPlaces = isNaN(options.decimalPlaces = Math.abs(options.decimalPlaces)) ? 0 : options.decimalPlaces;
    var prefix = options.prefix !== undefined ? options.prefix : '';
    var suffix = options.suffix !== undefined ? options.suffix : '';

    var countTo = function (timestamp) {
      if (!startTime) startTime = timestamp;
      var currentTime = timestamp - startTime;
      var progress = currentTime / endTime;
      progress = progress > 1 ? 1 : progress;
      currentVal = options.startVal + (options.endVal - options.startVal) * _this.easing(progress);
      currentVal = parseFloat(currentVal.toFixed(decimalPlaces));
      if (elem) elem.innerHTML = prefix + _this.formatNumber(currentVal) + suffix;
      if (progress < 1) reqAnimationFrame(countTo);
      if (progress === 1 && options.onComplete) options.onComplete();
    };

    reqAnimationFrame(countTo);
  }

  _this.easing = options.easingFn || function (t) {
    return --t * t * t + 1;
  };

  _this.formatNumber = function (num) {
    num = num.toFixed(options.decimalPlaces);
    num = num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    return num;
  };
}

在这个代码段中,我们定义了一个CountUp对象,它的参数是一个选项对象,包括:

  • el: DOM元素的id;
  • startVal: 开始计数的值;
  • endVal: 结束计数的值;
  • duration: 计数持续时间;
  • prefix: 数字前缀;
  • suffix: 数字后缀;
  • decimalPlaces: 小数点位数;
  • easingFn: 缓动函数;
  • onComplete: 计数结束回调函数。

在这个对象中,我们同样通过requestAnimationFrame方法来实现计数器的更新,并在计数结束之后删除计数节点。同时,我们提供了一个_easing私有函数来进行缓动运动。我们还提供了一个_formatNumber私有函数来添加千位分隔符并保留小数点位数。最后,我们暴露了一个start方法来启动计数器的计数。

以上就是制作自己的countUp.js插件的完整攻略,其中给出了两个示例说明。希望这些内容能够对你有所帮助。