Butterfly主题开发版基本已经实现完全去jquery化,而本帖有使用到jquery,可以考虑使用备选方案中的原生JS计时器。

备选方案
  1. [Blogroot]\_config.butterfly.ymlfooter配置项添加时间栏,如果已经有在custom_text写入过内容的,可以在合适的位置插入span标签。

        footer:
    owner:
    enable: true
    since: 2016
    - custom_text:
    + custom_text: <span id="runtime"></span>
    copyright: false # Copyright of theme and framework
    ICP: # Chinese ICP License
    enable: false
    url:
    text:
    icon: /img/icp.png
  2. [Blogroot]\themes\butterfly\source\js\目录下新建runtime.js

    setInterval(() => {
    let create_time = Math.round(new Date('2019-04-17 00:00:00').getTime() / 1000); //在此行修改建站时间
    let timestamp = Math.round((new Date().getTime() + 8 * 60 * 60 * 1000) / 1000);
    let second = timestamp - create_time;
    let time = new Array(0, 0, 0, 0, 0);
    if (second >= 365 * 24 * 3600) {
    time[0] = parseInt(second / (365 * 24 * 3600));
    second %= 365 * 24 * 3600;
    }
    if (second >= 24 * 3600) {
    time[1] = parseInt(second / (24 * 3600));
    second %= 24 * 3600;
    }
    if (second >= 3600) {
    time[2] = parseInt(second / 3600);
    second %= 3600;
    }
    if (second >= 60) {
    time[3] = parseInt(second / 60);
    second %= 60;
    }
    if (second > 0) {
    time[4] = second;
    }
    currentTimeHtml = '网站已运行' + time[0] + ' 年 ' + time[1] + ' 天 ' + time[2] + ' 时 ' + time[3] + ' 分 ' + time[4] + ' 秒';
    document.getElementById("runtime").innerHTML = currentTimeHtml;
    }, 1000);
  3. [Blogroot]\_config.butterfly.ymlinject引入文件。

        inject:
    head:
    bottom:
    + - <script async src="/js/runtime.js"></script>

页脚翻页时钟计时

  1. 参考内容:jquery.flipcountdown翻页定时器倒计时插件支持时分秒倒计时时间表
  2. 改动范围:添加pjax重载,修复计算时间逻辑,避免出现负数的尴尬。

  3. 可以直接下载教程涉及的静态资源,按指示添加到相应目录。
  4. 虽然说是页脚计时器,但不一定非要放在页脚。位置取决于便签注入的位置。而且也不局限于博客,理论上任何静态页面都适用。
  5. 由于本教程的页脚计时器依赖于jquery,与Metro4框架有所冲突,所以不建议在使用了这个框架的页面上(例如本人的主页,说多了都是泪)使用。

修改步骤

  1. [Blogroot]\_config.butterfly.ymlfooter配置项添加时间栏,如果已经有在custom_text写入过内容的,可以在合适的位置插入span标签。

        footer:
    owner:
    enable: true
    since: 2016
    - custom_text:
    + custom_text: <span id="runtime"></span>
    copyright: false # Copyright of theme and framework
    ICP: # Chinese ICP License
    enable: false
    url:
    text:
    icon: /img/icp.png
  2. [Blogroot]\themes\butterfly\source\css\目录下新建flipcountdown.css

    .xdsoft_flipcountdown{display:inline-block;}

    .xdsoft_flipcountdown .xdsoft_digit{float:left;background-repeat:no-repeat;}
    .xdsoft_flipcountdown .xdsoft_clearex{clear:both;float:none;}


    .xdsoft_flipcountdown .xdsoft_digit{
    background-position:0px 0px;
    }
    .xdsoft_flipcountdown .xdsoft_digit.xdsoft_separator,.xdsoft_flipcountdown .xdsoft_digit.xdsoft_dot{
    opacity:0.9;
    }
    .xdsoft_flipcountdown.xdsoft_size_lg .xdsoft_digit{
    width:53px;
    height:76px;
    background-image:url(/img/digit-lg.png);
    }
    .xdsoft_flipcountdown.xdsoft_size_lg .xdsoft_digit.xdsoft_space,
    .xdsoft_flipcountdown.xdsoft_size_lg .xdsoft_digit.xdsoft_separator,
    .xdsoft_flipcountdown.xdsoft_size_lg .xdsoft_digit.xdsoft_dot{
    width:14px;
    background-position:-19px -4620px;
    }
    .xdsoft_flipcountdown.xdsoft_size_lg .xdsoft_digit.xdsoft_dot{
    background-position:-41px -4620px;
    }
    .xdsoft_flipcountdown.xdsoft_size_lg .xdsoft_digit.xdsoft_space{
    background-position:-100px -4620px;
    }

    .xdsoft_flipcountdown.xdsoft_size_md .xdsoft_digit{
    width:36px;
    height:51px;
    background-image:url(/img/digit-md.png);
    }
    .xdsoft_flipcountdown.xdsoft_size_md .xdsoft_digit.xdsoft_space,
    .xdsoft_flipcountdown.xdsoft_size_md .xdsoft_digit.xdsoft_separator,
    .xdsoft_flipcountdown.xdsoft_size_md .xdsoft_digit.xdsoft_dot{
    width:10px;
    background-position:-13px -3120px;
    }
    .xdsoft_flipcountdown.xdsoft_size_sm .xdsoft_digit{
    width:24px;
    height:34px;
    background-image:url(/img/digit-sm.png);
    }
    .xdsoft_flipcountdown.xdsoft_size_sm .xdsoft_digit.xdsoft_space,
    .xdsoft_flipcountdown.xdsoft_size_sm .xdsoft_digit.xdsoft_separator,
    .xdsoft_flipcountdown.xdsoft_size_sm .xdsoft_digit.xdsoft_dot{
    width:10px;
    background-position:-6px -2100px;
    }
    .xdsoft_flipcountdown.xdsoft_size_xs .xdsoft_digit{
    width:16px;
    height:23px;
    background-image:url(/img/digit-xs.png);
    }
    .xdsoft_flipcountdown.xdsoft_size_xs .xdsoft_digit.xdsoft_space,
    .xdsoft_flipcountdown.xdsoft_size_xs .xdsoft_digit.xdsoft_separator,
    .xdsoft_flipcountdown.xdsoft_size_xs .xdsoft_digit.xdsoft_dot{
    width:5px;
    background-position:-5px -1440px;
    }
  3. [Blogroot]\themes\butterfly\source\js\目录下新建flipcountdown.jsruntime.js

    • flipcountdown.js

      /**
      * @preserve jQuery flipcountdown plugin v3.0.4
      * @homepage http://xdsoft.net/jqplugins/flipcountdown/
      * (c) 2013, Chupurnov Valeriy.
      */
      (function($){
      jQuery.fn.flipCountDown = jQuery.fn.flipcountdown = function( _options ){
      var default_options = {
      showHour :true,
      showMinute :true,
      showSecond :true,
      am :false,

      tzoneOffset :0,
      speedFlip :60,
      period :1000,
      tick :function(){
      return new Date();
      },
      autoUpdate :true,
      size :'md'
      },

      sizes = {
      lg:77,
      md:52,
      sm:35,
      xs:24
      },

      createFlipCountDown = function( $box ){
      var $flipcountdown = $('<div class="xdsoft_flipcountdown"></div>'),
      $clearex = $('<div class="xdsoft_clearex"></div>'),

      options = $.extend({},default_options),

      timer = 0,

      _animateRange = function( box,a,b ){
      _animateOne( box,a,(a>b&&!(a==9&&b==0))?-1:1,!(a==9&&b==0)?Math.abs(a-b):1 );
      },

      _animateOne = function( box,a,arrow,range ){
      if( range<1 )
      return;

      _setMargin(box,-(a*6*sizes[options.size]+1),1,arrow,function(){
      _animateOne(box,a+arrow,arrow,range-1);
      },range);
      },

      _setMargin = function( box, marginTop, rec, arrow,callback,range){
      if( marginTop<=-sizes[options.size]*60 )
      marginTop = -1;
      box.css('background-position','0px '+marginTop+'px' );
      if( rec<=6 ){
      setTimeout(function(){
      _setMargin(box, marginTop-arrow*sizes[options.size], ++rec, arrow, callback,range);
      },parseInt(options.speedFlip/range));
      }else
      callback();
      },

      blocks = [],

      _typeCompare = function ( a,b ){
      return a&&b&&(
      (a==b)||
      (/^[0-9]+$/.test(a+''+b))||
      (/^[:.\s]+$/.test(a+''+b))
      );
      },

      _generate = function( chars ){
      if( !(chars instanceof Array) || !chars.length )
      return false;
      for( var i = 0, n = chars.length;i<n;i++ ){
      if( !blocks[i] ){
      blocks[i] = $('<div class="xdsoft_digit"></div>');
      $clearex.before(blocks[i]);
      }
      if( blocks[i].data('value')!=chars[i] ){
      if( !_typeCompare(blocks[i].data('value'),chars[i]) ){
      blocks[i]
      .removeClass('xdsoft_separator')
      .removeClass('xdsoft_dot');
      switch( chars[i] ){
      case ':':blocks[i].addClass('xdsoft_separator');break;
      case '.':blocks[i].addClass('xdsoft_dot');break;
      case ' ':blocks[i].addClass('xdsoft_space');break;
      }
      }
      if( !isNaN(chars[i]) ){
      var old = parseInt(blocks[i].data('value')),
      ii = parseInt(blocks[i].data('i')),
      crnt = parseInt(chars[i]);
      if( isNaN(old)||i!=ii ){
      old = (crnt-1)<0?9:crnt-1;
      }
      _animateRange(blocks[i],old,crnt);
      }
      blocks[i].data('value',chars[i]);
      blocks[i].data('i',i);
      }
      }
      if( blocks.length>chars.length ){
      for(;i<blocks.length;i++ ){
      blocks[i][0].parentNode.removeChild(blocks[i][0]);
      delete blocks[i];
      }
      blocks.splice(chars.length);
      }

      },

      counter = 0,

      _calcMoment = function(){
      var value = '1',chars = [];
      if(options.tick)
      value = (options.tick instanceof Function)?options.tick.call($box,counter):options.tick;

      if( typeof value!=='undefined' ){
      switch( value.constructor ){
      case Date:
      var h = (value.getHours()+options.tzoneOffset)%(options.am?12:24);

      if( options.showHour ){
      chars.push(parseInt(h/10));
      chars.push(h%10);
      }

      if( options.showHour && (options.showMinute || options.showSecond) )
      chars.push(':');

      if( options.showMinute ){
      chars.push(parseInt(value.getMinutes()/10));
      chars.push(value.getMinutes() % 10);
      }

      if( options.showMinute && options.showSecond )
      chars.push(':');

      if( options.showSecond ){
      chars.push(parseInt(value.getSeconds()/10));
      chars.push(value.getSeconds() % 10);
      }
      break;
      case String:
      chars = value.replace(/[^0-9\:\.\s]/g,'').split('');
      break;
      case Number:
      chars = value.toString().split('');
      break;
      }
      _generate(chars);
      }
      };

      $flipcountdown
      .append($clearex)
      .on('xdinit.xdsoft',function(){
      clearInterval(timer);
      if( options.autoUpdate )
      timer = setInterval( _calcMoment,options.period );
      _calcMoment();
      });

      $box.data('setOptions',function( _options ){
      options = $.extend({},options,_options);
      if( !sizes[options.size] )
      options.size = 'lg';
      $flipcountdown
      .addClass('xdsoft_size_'+options.size)
      .trigger('xdinit.xdsoft');
      });
      $box.append($flipcountdown);
      };
      return this.each(function(){
      var $box = $(this);
      if( !$box.data('setOptions') ){
      $box.addClass('xdsoft')
      createFlipCountDown($box);
      }
      $box.data('setOptions')&&
      $.isFunction($box.data('setOptions'))&&
      $box.data('setOptions')(_options);
      });
      }
      })(jQuery);
    • runtime.js

      $(function(){
      var NY = Math.round((new Date('4/17/2019 00:00:00')).getTime()/1000); //Date修改为你的建站时间。
      $('#runtime').flipcountdown({
      size:"xs",//可以自定义翻页计时器大小。从大到小依次是lg、md、sm、xs。
      tick:function(){
      var nol = function(h){
      return h>9?h:'0'+h;
      }
      var range = Math.abs(Math.round((new Date()).getTime()/1000)-NY),
      secday = 86400, sechour = 3600,
      days = parseInt(range/secday),
      hours = parseInt((range%secday)/sechour),
      min = parseInt(((range%secday)%sechour)/60),
      sec = ((range%secday)%sechour)%60;
      return nol(days)+' '+nol(hours)+' '+nol(min)+' '+nol(sec);
      }
      });
      });
  4. 将下载的翻页时钟图片添加到[Blogroot]\themes\butterfly\source\img\目录下。

  5. [Blogroot]\_config.butterfly.ymlinject引入文件。

    • 其中jquery为依赖。最新版butterfly主题的CDN中自带,无需添加。
    • runtime.js依赖于flipcountdown.js,所以flipcountdown.js必须在runtime.js之前引入。
    • data-pjax属性为butterfly的pjax.pug中自带的重载函数。由于这里起重载作用的关键类只有runtime.js,其他都是依赖项,所以只要给runtime.js添加data-pjax属性即可。
        inject:
    head:
    + - <link rel="stylesheet" href="/css/flipcountdown.css">
    bottom:
    + - <script src="https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script>
    + - <script src="/js/flipcountdown.js"></script>
    + - <script data-pjax src="/js/runtime.js"></script>