Modify countdown script to allow for multiple countdowns per page

30 second countdown timer javascript
javascript countdown timer seconds
javascript countdown timer code
javascript countdown timer codepen
simple countdown timer html
javascript countdown timer hours, minutes, seconds
javascript countdown timer with user input
javascript countdown timer with start button

I am utilizing the following script from CodePen

// Create Countdown
var Countdown = {

    // Backbone-like structure
    $el: $('.countdown'),

    // Params
    countdown_interval: null,
    total_seconds     : 0,

    // Initialize the countdown  
    init: function() {

    // DOM
        this.$ = {
        hours  : this.$el.find('.bloc-time.hours .figure'),
        minutes: this.$el.find('.bloc-time.min .figure'),
        seconds: this.$el.find('.bloc-time.sec .figure')
    };

    // Init countdown values
    this.values = {
            hours  : this.$.hours.parent().attr('data-init-value'),
        minutes: this.$.minutes.parent().attr('data-init-value'),
        seconds: this.$.seconds.parent().attr('data-init-value'),
    };

    // Initialize total seconds
    this.total_seconds = this.values.hours * 60 * 60 + (this.values.minutes * 60) + this.values.seconds;

    // Animate countdown to the end 
    this.count();    
    },

    count: function() {

    var that    = this,
        $hour_1 = this.$.hours.eq(0),
        $hour_2 = this.$.hours.eq(1),
        $min_1  = this.$.minutes.eq(0),
        $min_2  = this.$.minutes.eq(1),
        $sec_1  = this.$.seconds.eq(0),
        $sec_2  = this.$.seconds.eq(1);

        this.countdown_interval = setInterval(function() {

        if(that.total_seconds > 0) {

            --that.values.seconds;              

            if(that.values.minutes >= 0 && that.values.seconds < 0) {

                that.values.seconds = 59;
                --that.values.minutes;
            }

            if(that.values.hours >= 0 && that.values.minutes < 0) {

                that.values.minutes = 59;
                --that.values.hours;
            }

            // Update DOM values
            // Hours
            that.checkHour(that.values.hours, $hour_1, $hour_2);

            // Minutes
            that.checkHour(that.values.minutes, $min_1, $min_2);

            // Seconds
            that.checkHour(that.values.seconds, $sec_1, $sec_2);

            --that.total_seconds;
        }
        else {
            clearInterval(that.countdown_interval);
        }
    }, 1000);    
    },

    animateFigure: function($el, value) {

        var that         = this,
                $top         = $el.find('.top'),
            $bottom      = $el.find('.bottom'),
            $back_top    = $el.find('.top-back'),
            $back_bottom = $el.find('.bottom-back');

    // Before we begin, change the back value
    $back_top.find('span').html(value);

    // Also change the back bottom value
    $back_bottom.find('span').html(value);

    // Then animate
    TweenMax.to($top, 0.8, {
        rotationX           : '-180deg',
        transformPerspective: 300,
            ease                : Quart.easeOut,
        onComplete          : function() {

            $top.html(value);

            $bottom.html(value);

            TweenMax.set($top, { rotationX: 0 });
        }
    });

    TweenMax.to($back_top, 0.8, { 
        rotationX           : 0,
        transformPerspective: 300,
            ease                : Quart.easeOut, 
        clearProps          : 'all' 
    });    
    },

    checkHour: function(value, $el_1, $el_2) {

    var val_1       = value.toString().charAt(0),
        val_2       = value.toString().charAt(1),
        fig_1_value = $el_1.find('.top').html(),
        fig_2_value = $el_2.find('.top').html();

    if(value >= 10) {

        // Animate only if the figure has changed
        if(fig_1_value !== val_1) this.animateFigure($el_1, val_1);
        if(fig_2_value !== val_2) this.animateFigure($el_2, val_2);
    }
    else {

        // If we are under 10, replace first figure with 0
        if(fig_1_value !== '0') this.animateFigure($el_1, 0);
        if(fig_2_value !== val_1) this.animateFigure($el_2, val_1);
    }    
    }
};

// Let's go !
Countdown.init();

I have been trying to figure out for several hours how to modify it to support multiple countdown timers per page.

My approach so far was to try adding a numeric counter so that each "countdown" element gets a unique class, and then modifying the script to run on each element but this did not work and I don't think it will.

I'm not sure how else to approach it though so would appreciate some input.


You can create a new instance of this object with just a little bit of refactoring by converting it into a function.

For example, if you clone your <div class="countdown"/> HTML, and in JS you call:

new Countdown($($('.countdown')[0])).init();
new Countdown($($('.countdown')[1])).init();

Or, alternatively you could also initialize all .countdowns on page with:

$('.countdown').each((_, el) => (new Countdown($(el)).init()));

you will have two unique instances of the countdown.

// Create Countdown
function Countdown(node) {
  this.$el = node;
  this.countdown_interval = null;
  this.total_seconds = 0;
  this.init = function() {
    // DOM
    this.$ = {
      hours: this.$el.find('.bloc-time.hours .figure'),
      minutes: this.$el.find('.bloc-time.min .figure'),
      seconds: this.$el.find('.bloc-time.sec .figure')
    };

    // Init countdown values
    this.values = {
      hours: this.$.hours.parent().attr('data-init-value'),
      minutes: this.$.minutes.parent().attr('data-init-value'),
      seconds: this.$.seconds.parent().attr('data-init-value'),
    };

    // Initialize total seconds
    this.total_seconds = (this.values.hours * 60 * 60) +
      (this.values.minutes * 60) +
      this.values.seconds;
    // Animate countdown to the end 
    this.count();
  };
  this.count = function() {
    let that = this,
      $hour_1 = this.$.hours.eq(0),
      $hour_2 = this.$.hours.eq(1),
      $min_1 = this.$.minutes.eq(0),
      $min_2 = this.$.minutes.eq(1),
      $sec_1 = this.$.seconds.eq(0),
      $sec_2 = this.$.seconds.eq(1);

    this.countdown_interval = setInterval(function() {
      if (that.total_seconds > 0) {
        --that.values.seconds;
        if (that.values.minutes >= 0 && that.values.seconds < 0) {
          that.values.seconds = 59;
          --that.values.minutes;
        }

        if (that.values.hours >= 0 && that.values.minutes < 0) {
          that.values.minutes = 59;
          --that.values.hours;
        }

        // Update DOM values
        // Hours
        that.checkHour(that.values.hours, $hour_1, $hour_2);
        // Minutes
        that.checkHour(that.values.minutes, $min_1, $min_2);
        // Seconds
        that.checkHour(that.values.seconds, $sec_1, $sec_2);

        --that.total_seconds;
      } else {
        clearInterval(that.countdown_interval);
      }
    }, 1000);
  };
  this.animateFigure = function($el, value) {
    let that = this,
      $top = $el.find('.top'),
      $bottom = $el.find('.bottom'),
      $back_top = $el.find('.top-back'),
      $back_bottom = $el.find('.bottom-back');

    // Before we begin, change the back value
    $back_top.find('span').html(value);

    // Also change the back bottom value
    $back_bottom.find('span').html(value);

    // Then animate
    TweenMax.to($top, 0.8, {
      rotationX: '-180deg',
      transformPerspective: 300,
      ease: Quart.easeOut,
      onComplete: function() {
        $top.html(value);
        $bottom.html(value);
        TweenMax.set($top, {
          rotationX: 0
        });
      }
    });

    TweenMax.to($back_top, 0.8, {
      rotationX: 0,
      transformPerspective: 300,
      ease: Quart.easeOut,
      clearProps: 'all'
    });
  };
  this.checkHour = function(value, $el_1, $el_2) {
    let val_1 = value.toString().charAt(0),
      val_2 = value.toString().charAt(1),
      fig_1_value = $el_1.find('.top').html(),
      fig_2_value = $el_2.find('.top').html();

    if (value >= 10) {
      // Animate only if the figure has changed
      if (fig_1_value !== val_1) this.animateFigure($el_1, val_1);
      if (fig_2_value !== val_2) this.animateFigure($el_2, val_2);
    } else {
      // If we are under 10, replace first figure with 0
      if (fig_1_value !== '0') this.animateFigure($el_1, 0);
      if (fig_2_value !== val_1) this.animateFigure($el_2, val_1);
    }
  }
}

// Let's go !
new Countdown($($('.countdown')[0])).init();
new Countdown($($('.countdown')[1])).init();

// Alternatively you could also initialize all countdowns on page with:
// $('.countdown').each((i, el) => (new Countdown($(el)).init()));
body {
  background-color: #f2f1ed;
}

.wrap {
  position: absolute;
  bottom: 0;
  top: 0;
  left: 0;
  right: 0;
  margin: auto;
  height: 310px;
}

a {
  text-decoration: none;
  color: #1a1a1a;
}

h1 {
  margin-bottom: 60px;
  text-align: center;
  font: 300 2.25em "Lato";
  text-transform: uppercase;
}

h1 strong {
  font-weight: 400;
  color: #ea4c4c;
}

h2 {
  margin-bottom: 80px;
  text-align: center;
  font: 300 0.7em "Lato";
  text-transform: uppercase;
}

h2 strong {
  font-weight: 400;
}

.countdown {
  width: 720px;
  margin: 4px 0;
  display: inline-block;
}

.countdown .bloc-time {
  float: left;
  margin-right: 45px;
  text-align: center;
}

.countdown .bloc-time:last-child {
  margin-right: 0;
}

.countdown .count-title {
  display: block;
  margin-bottom: 15px;
  font: normal 0.94em "Lato";
  color: #1a1a1a;
  text-transform: uppercase;
}

.countdown .figure {
  position: relative;
  float: left;
  height: 110px;
  width: 100px;
  margin-right: 10px;
  background-color: #fff;
  border-radius: 8px;
  -moz-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
  -webkit-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
  box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
}

.countdown .figure:last-child {
  margin-right: 0;
}

.countdown .figure>span {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  font: normal 5.94em/107px "Lato";
  font-weight: 700;
  color: #de4848;
}

.countdown .figure .top:after,
.countdown .figure .bottom-back:after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.countdown .figure .top {
  z-index: 3;
  background-color: #f7f7f7;
  transform-origin: 50% 100%;
  -webkit-transform-origin: 50% 100%;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px;
  border-top-left-radius: 10px;
  -moz-border-radius-topright: 10px;
  -webkit-border-top-right-radius: 10px;
  border-top-right-radius: 10px;
  -moz-transform: perspective(200px);
  -ms-transform: perspective(200px);
  -webkit-transform: perspective(200px);
  transform: perspective(200px);
}

.countdown .figure .bottom {
  z-index: 1;
}

.countdown .figure .bottom:before {
  content: "";
  position: absolute;
  display: block;
  top: 0;
  left: 0;
  width: 100%;
  height: 50%;
  background-color: rgba(0, 0, 0, 0.02);
}

.countdown .figure .bottom-back {
  z-index: 2;
  top: 0;
  height: 50%;
  overflow: hidden;
  background-color: #f7f7f7;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px;
  border-top-left-radius: 10px;
  -moz-border-radius-topright: 10px;
  -webkit-border-top-right-radius: 10px;
  border-top-right-radius: 10px;
}

.countdown .figure .bottom-back span {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  margin: auto;
}

.countdown .figure .top,
.countdown .figure .top-back {
  height: 50%;
  overflow: hidden;
  -moz-backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.countdown .figure .top-back {
  z-index: 4;
  bottom: 0;
  background-color: #fff;
  -webkit-transform-origin: 50% 0;
  transform-origin: 50% 0;
  -moz-transform: perspective(200px) rotateX(180deg);
  -ms-transform: perspective(200px) rotateX(180deg);
  -webkit-transform: perspective(200px) rotateX(180deg);
  transform: perspective(200px) rotateX(180deg);
  -moz-border-radius-bottomleft: 10px;
  -webkit-border-bottom-left-radius: 10px;
  border-bottom-left-radius: 10px;
  -moz-border-radius-bottomright: 10px;
  -webkit-border-bottom-right-radius: 10px;
  border-bottom-right-radius: 10px;
}

.countdown .figure .top-back span {
  position: absolute;
  top: -100%;
  left: 0;
  right: 0;
  margin: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrap">
  <h1>Draft <strong>Countdown</strong></h1>

  <!-- Countdown #1 -->
  <div class="countdown">
    <div class="bloc-time hours" data-init-value="24">
      <span class="count-title">Hours</span>

      <div class="figure hours hours-1">
        <span class="top">2</span>
        <span class="top-back">
          <span>2</span>
        </span>
        <span class="bottom">2</span>
        <span class="bottom-back">
          <span>2</span>
        </span>
      </div>

      <div class="figure hours hours-2">
        <span class="top">4</span>
        <span class="top-back">
          <span>4</span>
        </span>
        <span class="bottom">4</span>
        <span class="bottom-back">
          <span>4</span>
        </span>
      </div>
    </div>

    <div class="bloc-time min" data-init-value="0">
      <span class="count-title">Minutes</span>

      <div class="figure min min-1">
        <span class="top">0</span>
        <span class="top-back">
          <span>0</span>
        </span>
        <span class="bottom">0</span>
        <span class="bottom-back">
          <span>0</span>
        </span>
      </div>

      <div class="figure min min-2">
        <span class="top">0</span>
        <span class="top-back">
          <span>0</span>
        </span>
        <span class="bottom">0</span>
        <span class="bottom-back">
          <span>0</span>
        </span>
      </div>
    </div>

    <div class="bloc-time sec" data-init-value="0">
      <span class="count-title">Seconds</span>

      <div class="figure sec sec-1">
        <span class="top">0</span>
        <span class="top-back">
          <span>0</span>
        </span>
        <span class="bottom">0</span>
        <span class="bottom-back">
          <span>0</span>
        </span>
      </div>

      <div class="figure sec sec-2">
        <span class="top">0</span>
        <span class="top-back">
          <span>0</span>
        </span>
        <span class="bottom">0</span>
        <span class="bottom-back">
          <span>0</span>
        </span>
      </div>
    </div>
  </div>

  <div class="countdown">
    <div class="bloc-time hours" data-init-value="4">
      <span class="count-title">Hours</span>

      <div class="figure hours hours-1">
        <span class="top">0</span>
        <span class="top-back">
          <span>0</span>
        </span>
        <span class="bottom">0</span>
        <span class="bottom-back">
          <span>0</span>
        </span>
      </div>

      <div class="figure hours hours-2">
        <span class="top">4</span>
        <span class="top-back">
          <span>4</span>
        </span>
        <span class="bottom">4</span>
        <span class="bottom-back">
          <span>4</span>
        </span>
      </div>
    </div>

    <div class="bloc-time min" data-init-value="30">
      <span class="count-title">Minutes</span>

      <div class="figure min min-1">
        <span class="top">3</span>
        <span class="top-back">
          <span>3</span>
        </span>
        <span class="bottom">3</span>
        <span class="bottom-back">
          <span>3</span>
        </span>
      </div>

      <div class="figure min min-2">
        <span class="top">0</span>
        <span class="top-back">
          <span>0</span>
        </span>
        <span class="bottom">0</span>
        <span class="bottom-back">
          <span>0</span>
        </span>
      </div>
    </div>

    <div class="bloc-time sec" data-init-value="30">
      <span class="count-title">Seconds</span>

      <div class="figure sec sec-1">
        <span class="top">3</span>
        <span class="top-back">
          <span>3</span>
        </span>
        <span class="bottom">3</span>
        <span class="bottom-back">
          <span>3</span>
        </span>
      </div>

      <div class="figure sec sec-2">
        <span class="top">0</span>
        <span class="top-back">
          <span>0</span>
        </span>
        <span class="bottom">0</span>
        <span class="bottom-back">
          <span>0</span>
        </span>
      </div>
    </div>
  </div>
</div>

Modify countdown script to allow for multiple countdowns per page, I am utilizing the following script from CodePen: https://codepen.io/doriancami/​pen/jEJvaV // Create Countdown var Countdown  Mun Rashid has modified the JavaScript code by using object wrapping to allow for multiple countdowns on one page. Download Mun's JavaScript code here. Download the sample HTML here. Tilesh Khatri has written a simplified script based on the countdown code that displays multiple clocks on one page.


As a jQuery plugin it could go this way (you can customize it further):

// Create Countdown Plugin
$.fn.fancyCountdown = function() {
 
    return this.each(function() {
        
		var that=this;
		var $el=$(this);
		
		that.values = {
			titleHours: 'Hours',
			titleMinutes: 'Minutes',
			titleSeconds: 'Seconds'
		};
		
		if( $el.data('settings') ) {
			that.values = $el.data('settings');
		} else {
			that.values = $.extend( {}, that.values, $el.data() );
		};
		var explodeTime = that.values.time.split(':');
		that.values.hours = explodeTime[0]*1;
		that.values.minutes = explodeTime[1]*1;
		that.values.seconds = explodeTime[2]*1;
		that.values.hours1 = explodeTime[0][0];
		that.values.hours2 = explodeTime[0][1];
		that.values.minutes1 = explodeTime[1][0];
		that.values.minutes2 = explodeTime[1][1];
		that.values.seconds1 = explodeTime[2][0];
		that.values.seconds2 = explodeTime[2][1];
		that.values.totalSeconds = that.values.hours*60*60 + that.values.minutes*60 + that.values.seconds;
		that.values.template = '\
			<span class="top">#</span>\
			<span class="top-back">\
				<span>#</span>\
			</span>\
			<span class="bottom">#</span>\
			<span class="bottom-back">\
				<span>#</span>\
			</span>\
		';
		that.countdownInterval = null;
		
		if( !$el.hasClass('countdown-engaged') ) {
		
			$el.addClass('countdown-engaged');

			// Initialize the countdown  
			that.init=function() {

				// DOM
				that.createDom();
				that.$ = {
					hours: $el.find('.bloc-time.hours .figure'),
					minutes: $el.find('.bloc-time.min .figure'),
					seconds: $el.find('.bloc-time.sec .figure')
				};

				// Animate countdown to the end 
				that.count();
			};
			
			that.createDom = function() {
				var html = '\
					<div class="bloc-time hours">\
						<span class="count-title">' + that.values.titleHours + '</span>\
						<div class="figure hours hours-1">\
							' + that.values.template.replace(/#/g, that.values.hours1) + '\
						</div>\
						<div class="figure hours hours-2">\
							' + that.values.template.replace(/#/g, that.values.hours2) + '\
						</div>\
					</div>\
					<div class="bloc-time min">\
						<span class="count-title">' + that.values.titleMinutes + '</span>\
						<div class="figure min min-1">\
							' + that.values.template.replace(/#/g, that.values.minutes1) + '\
						</div>\
						<div class="figure min min-2">\
							' + that.values.template.replace(/#/g, that.values.minutes2) + '\
						</div>\
					</div>\
					<div class="bloc-time sec">\
						<span class="count-title">' + that.values.titleSeconds + '</span>\
						<div class="figure sec sec-1">\
							' + that.values.template.replace(/#/g, that.values.seconds1) + '\
						</div>\
						<div class="figure sec sec-2">\
							' + that.values.template.replace(/#/g, that.values.seconds2) + '\
						</div>\
					</div>\
				';
				$el.html(html);
			};

			that.count = function() {
				var $hour_1 = that.$.hours.eq(0),
					$hour_2 = that.$.hours.eq(1),
					$min_1 = that.$.minutes.eq(0),
					$min_2 = that.$.minutes.eq(1),
					$sec_1 = that.$.seconds.eq(0),
					$sec_2 = that.$.seconds.eq(1);

				that.countdownInterval = setInterval(function() {

					if (that.values.totalSeconds > 0) {

						--that.values.seconds;

						if (that.values.minutes >= 0 && that.values.seconds < 0) {
							that.values.seconds = 59;
							--that.values.minutes;
						}

						if (that.values.hours >= 0 && that.values.minutes < 0) {
							that.values.minutes = 59;
							--that.values.hours;
						}

						// Update DOM values
						// Hours
						that.checkHour(that.values.hours, $hour_1, $hour_2);

						// Minutes
						that.checkHour(that.values.minutes, $min_1, $min_2);

						// Seconds
						that.checkHour(that.values.seconds, $sec_1, $sec_2);

						--that.values.totalSeconds;
					} else {
						clearInterval(that.countdownInterval);
					};
				}, 1000);
			};

			that.animateFigure = function($el, value) {

				var $top = $el.find('.top'),
					$bottom = $el.find('.bottom'),
					$back_top = $el.find('.top-back'),
					$back_bottom = $el.find('.bottom-back');

				// Before we begin, change the back value
				$back_top.find('span').html(value);

				// Also change the back bottom value
				$back_bottom.find('span').html(value);

				// Then animate
				TweenMax.to($top, 0.8, {
					rotationX: '-180deg',
					transformPerspective: 300,
					ease: Quart.easeOut,
					onComplete: function() {

						$top.html(value);

						$bottom.html(value);

						TweenMax.set($top, {
							rotationX: 0
						});
					}
				});

				TweenMax.to($back_top, 0.8, {
					rotationX: 0,
					transformPerspective: 300,
					ease: Quart.easeOut,
					clearProps: 'all'
				});
			};

			that.checkHour=function(value, $el_1, $el_2) {

				var val_1 = value.toString().charAt(0),
					val_2 = value.toString().charAt(1),
					fig_1_value = $el_1.find('.top').html(),
					fig_2_value = $el_2.find('.top').html();

				if (value >= 10) {

					// Animate only if the figure has changed
					if (fig_1_value !== val_1) that.animateFigure($el_1, val_1);
					if (fig_2_value !== val_2) that.animateFigure($el_2, val_2);
				} else {

					// If we are under 10, replace first figure with 0
					if (fig_1_value !== '0') that.animateFigure($el_1, 0);
					if (fig_2_value !== val_1) that.animateFigure($el_2, val_1);
				}
			};
			
		};
		
		that.init();
		
    });
 
};

$('.countdown').fancyCountdown();
body {
    background-color: #f2f1ed;
}

.wrap {
    margin: 0 auto;
    height: 310px;
}

a {
    text-decoration: none;
    color: #1a1a1a;
}

h1 {
    margin-bottom: 60px;
    text-align: center;
    font: 300 2.25em "Lato";
    text-transform: uppercase;
}

h1 strong {
    font-weight: 400;
    color: #ea4c4c;
}

h2 {
    margin-bottom: 80px;
    text-align: center;
    font: 300 0.7em "Lato";
    text-transform: uppercase;
}

h2 strong {
    font-weight: 400;
}

.countdown {
    width: 720px;
    margin: 0 auto;
}

.countdown .bloc-time {
    float: left;
    margin-right: 45px;
    text-align: center;
}

.countdown .bloc-time:last-child {
    margin-right: 0;
}

.countdown .count-title {
    display: block;
    margin-bottom: 15px;
    font: normal 0.94em "Lato";
    color: #1a1a1a;
    text-transform: uppercase;
}

.countdown .figure {
    position: relative;
    float: left;
    height: 110px;
    width: 100px;
    margin-right: 10px;
    background-color: #fff;
    border-radius: 8px;
    -moz-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
    -webkit-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
    box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
}

.countdown .figure:last-child {
    margin-right: 0;
}

.countdown .figure>span {
    position: absolute;
    left: 0;
    right: 0;
    margin: auto;
    font: normal 5.94em/107px "Lato";
    font-weight: 700;
    color: #de4848;
}

.countdown .figure .top:after,
.countdown .figure .bottom-back:after {
    content: "";
    position: absolute;
    z-index: -1;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.countdown .figure .top {
    z-index: 3;
    background-color: #f7f7f7;
    transform-origin: 50% 100%;
    -webkit-transform-origin: 50% 100%;
    -moz-border-radius-topleft: 10px;
    -webkit-border-top-left-radius: 10px;
    border-top-left-radius: 10px;
    -moz-border-radius-topright: 10px;
    -webkit-border-top-right-radius: 10px;
    border-top-right-radius: 10px;
    -moz-transform: perspective(200px);
    -ms-transform: perspective(200px);
    -webkit-transform: perspective(200px);
    transform: perspective(200px);
}

.countdown .figure .bottom {
    z-index: 1;
}

.countdown .figure .bottom:before {
    content: "";
    position: absolute;
    display: block;
    top: 0;
    left: 0;
    width: 100%;
    height: 50%;
    background-color: rgba(0, 0, 0, 0.02);
}

.countdown .figure .bottom-back {
    z-index: 2;
    top: 0;
    height: 50%;
    overflow: hidden;
    background-color: #f7f7f7;
    -moz-border-radius-topleft: 10px;
    -webkit-border-top-left-radius: 10px;
    border-top-left-radius: 10px;
    -moz-border-radius-topright: 10px;
    -webkit-border-top-right-radius: 10px;
    border-top-right-radius: 10px;
}

.countdown .figure .bottom-back span {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    margin: auto;
}

.countdown .figure .top,
.countdown .figure .top-back {
    height: 50%;
    overflow: hidden;
    -moz-backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}

.countdown .figure .top-back {
    z-index: 4;
    bottom: 0;
    background-color: #fff;
    -webkit-transform-origin: 50% 0;
    transform-origin: 50% 0;
    -moz-transform: perspective(200px) rotateX(180deg);
    -ms-transform: perspective(200px) rotateX(180deg);
    -webkit-transform: perspective(200px) rotateX(180deg);
    transform: perspective(200px) rotateX(180deg);
    -moz-border-radius-bottomleft: 10px;
    -webkit-border-bottom-left-radius: 10px;
    border-bottom-left-radius: 10px;
    -moz-border-radius-bottomright: 10px;
    -webkit-border-bottom-right-radius: 10px;
    border-bottom-right-radius: 10px;
}

.countdown .figure .top-back span {
    position: absolute;
    top: -100%;
    left: 0;
    right: 0;
    margin: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrap">
    <h1>Draft <strong>Countdown</strong></h1>
    <div class="countdown" data-time="22:30:00"></div>
</div>
<div class="wrap">
	<h1>Second <strong>Countdown</strong></h1>
    <div class="countdown" data-settings='{"time": "01:22:50", "titleHours": "Sati", "titleMinutes": "Minuti", "titleSeconds": "Sekunde"}'></div>
</div>

How To Create A Countdown Timer Using JavaScript, A countdown timer is an accurate timer that can be used for a website or blog to Display the clock on the page, and stop the clock when it reaches zero. First we calculate the time remaining by subtracting the deadline by current date and is over then “expired” will be displayed on the screen. INPUT : filter_none. edit to allow for all of the records in the table to come back, but I can't get the JavaScript and PHP to work together properly for multiple instancesI can get the multiple tables to appear, but the countdown section just changes from one table to another as if the JavaScript code isn't recognizing that I am trying to pull mutliple records.


I only kept the visual aspect in CSS (with some modifications) and I completely rewrote all the code in "pure" Javascript (no jQuery) and keeping the GSAP / TweenMax library.

You can put as many countDown as you want by filling in an array indicating the titles and durations etc.

There is only one setInterval handling the different countDown and it will stop with the last active countDown.

I chose this solution because using several setInterval at the same time seemed to me disproportionate for that, and unnecessarily overload the OS.

For greater accuracy, all countDowns are based on the system clock (and not on the call cycles of the setInterval, because they are "naturally" shifted and are therefore incompatible for any use of time measurement).

This script makes it possible to carry out 2 types of countDown: - for a fixed duration (eg 6 minutes for eggs) - either on a date (or time) end (ex: birthday, appointment ...)

The other interest of this script is that it generates on demand the set of elements html useful to the display of countDown on the page, and it allows to choose the display with the number of desired units

const myCountDowns= [ { title: 'timer <strong>24h</strong>'
                      , type : 'Hours'
                      , timer: '24h'
                      } 
                    , { title: 'Tea cup <strong>2\' 45"</strong>'
                      , type : 'Minutes'
                      , timer: '2m 45s'
                      } 
                    , { title: 'until the new year <strong>2020</strong>'
                      , type : 'Days'
                      , date : '01 01 2020' // local Month Day Year
                      } 
                    ] 

CountDown.BuildsAndRun( myCountDowns )

// ->type : 'Days'  or 'Hours' or 'Minutes' or 'seconds'
// set "timer" for time duration  otherwise set a "date" value

// timer string format is _number_UNIT where UNIT = 'd','h','m','s'  for Days, Hours, Minutes, Seconds
// ex : '3d 25m 6s'  = 3 days 0 hours 25 minutes, 6 seconds  (days = 0, 0 is defauls for all units)
// ex : '6s 3d 25m'  = the same, there is no order
// date format is JS Date format  see new Date( _STRING_ )

FULL CODE (on snippet below)

(function( CountDown )
  {
  // Private vars
  const domEndBody     = document.body.querySelector('script') || document.body // for countDowns insert place
      , eWrapp         = document.createElement('div')
      , eTitle         = document.createElement('h1')
      , eCountDown     = document.createElement('div')
      , eTimeBlock     = document.createElement('div')
      , eCountTitle    = document.createElement('span')
      , eFigure        = document.createElement('div')
      , counters       = []                              // list of CountDowns
      , one_Sec        = 1000
      , one_Min        = one_Sec * 60
      , one_Hour       = one_Min * 60 
      , one_Day        = one_Hour * 24
      , padZ =(val,sz) => ('0'.repeat(sz)+val.toString(10)).slice(-sz) // return string with leading zeros
      , Interface      = [ { xL:8, Title:'Days',    Fig:3 }            // titles & counts of figures
                         , { xL:5, Title:'Hours',   Fig:2 } 
                         , { xL:3, Title:'Minutes', Fig:2 } 
                         , { xL:0, Title:'Seconds', Fig:2 } 
                         ]
      , animOpt        = { rotationX: 0, transformPerspective: 300, ease: Quart.easeOut, clearProps: 'all' }

  var activeCounters   = 0

  // finalize countDown elements
  eWrapp.className      = 'wrap'
  eTitle.innerHTML      = 'F<strong>D</strong>'  // 'Draft <strong>Countdown</strong>'
  eCountDown.className  = 'countdown'
  eTimeBlock.className  = 'bloc-time'
  eCountTitle.className = 'count-title'
  eFigure.className     = 'figure'
  eFigure.innerHTML     = '<span class="top"        > </span>'
                        + ' <span class="top-back"   > <span> </span> </span>'
                        + ' <span class="bottom"     > </span>'
                        + ' <span class="bottom-back"> <span> </span> </span>'

  //Public Method ........................................................................
  CountDown.BuildsAndRun = function( TimerArray )
    {
    for (let TimerParms of TimerArray) 
      { CountDown_Build ( TimerParms ) }

    setTimeout(() => { CountDown_Run() }, 300);  // the Timeout is just for start spectacle
    }                 

  // Private Methods......................................................................
  CountDown_Build = function( parms )
    {
    let len = parms.type==='Hours'?6:parms.type==='Minutes'?4:parms.type==='seconds'?2:9
      , ctD = { lg     : len              // countDown number of figure (digits)
              , face   : ' '.repeat(len)  // actuel face of countDown
              , fig    : []               // array of firures (DOM elements)
              , ref    : counters.length  // ID  of this countDown
              , time   : null             // time to add to compute taget time for CountDown
              , target : null             // target Timie value
              , activ  : true             // to check if count down is activ or not ( finished )
              }
    // generate all Figures of CountDown          
    for(let i=len;i--;) {                     // from len to 0 (just my fav ninja)
      ctD.fig.push( eFigure.cloneNode(true) )
      }
    // CountDown DOM making
    let xWrapp     = eWrapp.cloneNode(true)
      , xTitle     = eTitle.cloneNode(true)
      , xCountDown = eCountDown.cloneNode(true)
      , noFig      = 0                          // ref on the first ctD.fig list (of figures)

    xTitle.innerHTML       = parms.title
    xWrapp.style.width = len===9?'1105px':len===6?'740px':len===4?'485px':'230px'
    //xCountDown.style.width = len===9?'1090px':len===6?'730px':len===4?'470px':'230px'

    xWrapp.appendChild(xTitle)
    xWrapp.appendChild(xCountDown)

    // making of bloc-time elements
    for(eBlk of Interface)
      {
      if(len>eBlk.xL)
        {
        let xTimeBlock  = eTimeBlock.cloneNode(true)
          , xCountTitle = eCountTitle.cloneNode(true)

        xCountTitle.textContent = eBlk.Title
        xTimeBlock.appendChild(xCountTitle)
        for(let f=eBlk.Fig;f--;)                        // (fav ninja again)
          { xTimeBlock.appendChild(ctD.fig[noFig++]) } // move figures inside
        xCountDown.appendChild(xTimeBlock)
        }
      }
    document.body.insertBefore(xWrapp, domEndBody)   // insert CountDowm on page

    // set count down initial values 
    if (parms.timer)   // in case of timer...
      {
      let TimeInfos = get_DHMS(parms.timer, len )
      ctD.time      = TimeInfos.add 
      counters.push( ctD )
      activeCounters++
      updateInterface( ctD.ref, TimeInfos.dis )  // show first figure faces
      }
    else if (parms.date) // in case of CountDown until date
      {
      ctD.target = new Date(parms.date);
      counters.push( ctD ) 
      if (showFaceOnNow( ctD.ref ))
        { activeCounters++ }
      }
    }
  CountDown_Run = function()
    {
    for (let elm of counters)
      { 
      if (elm.time)
        { elm.target = new Date().getTime() + elm.time }
      }
    let timerInterval = setInterval(_=>
      {
      counters.forEach((elm,ref)=>
        { 
        if ( elm.activ )
          {
          if (!showFaceOnNow( ref ))
            { activeCounters-- }
          }
        if ( activeCounters<=0 )
          { clearInterval(timerInterval) }  
        })
      }
      , one_Sec )
    }  
  showFaceOnNow = function(ref)
    {
    let now = new Date().getTime()
    , tim   = counters[ref].target - now
    , face  = '0'.repeat( counters[ref].lg )
    
    if (tim >= 0)
      {
      face  = padZ(Math.floor(tim / one_Day), 3)
      face += padZ((Math.floor((tim % one_Day ) / one_Hour)), 2)
      face += padZ((Math.floor((tim % one_Hour) / one_Min )), 2)
      face += padZ((Math.floor((tim % one_Min ) / one_Sec )), 2)
      face = padZ( face, counters[ref].lg )
      }
    else
      {
      counters[ref].activ = false
      }
    updateInterface ( ref, face)
    return counters[ref].activ
    }
  updateInterface = function(ref, newVal)
    {
    for(let p = counters[ref].lg ; p--;)  // update faces figures backward
      {
      if (counters[ref].face.charAt(p) !== newVal.charAt(p))
        {
        animateFigure( counters[ref].fig[p], newVal.charAt(p) )
        }
      }
    counters[ref].face = newVal
    }
  get_DHMS = function (timer_val, lg)
    {
    let vDelay = { d:0, h:0, m:0, s:0 }
      , vNum   = '0'
      , ret    = { add: 0, dis: ''}
    for (const c of timer_val)
      {
      if (/[0-9]/.test(c) )  vNum += c
      if (/[dhms]/.test(c) )
        {
        vDelay[c] = parseInt(vNum)
        vNum      = '0'
        }
      }
    ret.add = (vDelay.d*one_Day)+(vDelay.h*one_Hour)+(vDelay.m*one_Min)+(vDelay.s*one_Sec)
    ret.dis = (padZ(vDelay.d,3)+padZ(vDelay.h,2)+padZ(vDelay.m,2)+padZ(vDelay.s,2)).slice(-lg)
    return ret
    }
  animateFigure = function (domElm, newChar) 
    {
    let eTop         = domElm.querySelector('.top')
      , eBottom      = domElm.querySelector('.bottom')
      , eBack_top    = domElm.querySelector('.top-back')

    // Before we begin, change the back value and the back bottom value
    eBack_top.querySelector('span').textContent           = newChar
    domElm.querySelector('.bottom-back span').textContent = newChar
    
    TweenMax.to(eTop, 0.8,          // Then animate
      { rotationX           : '-180deg'
      , transformPerspective: 300
      , ease                : Quart.easeOut
      , onComplete          : function()
        {
        eTop.textContent    = newChar
        eBottom.textContent = newChar
        TweenMax.set(eTop, { rotationX: 0 })
        }
      })
    TweenMax.to(eBack_top, 0.8, animOpt)
    }
  }( window.CountDown = window.CountDown || {}));


/********************************************************************************************/


const myCountDowns= [ { title: 'timer <strong>24h</strong>'
                      , type : 'Hours'
                      , timer: '24h'
                      } 
                    , { title: 'Tea cup <strong>2\' 45"</strong>'
                      , type : 'Minutes'
                      , timer: '2m 45s'
                      } 
                    , { title: 'until the new year <strong>2020</strong>'
                      , type : 'Days'
                      , date : '01 01 2020' // local Month Day Year
                      } 
                    ] 

CountDown.BuildsAndRun( myCountDowns )


// ->type : 'Days'  or 'Hours' or 'Minutes' or 'seconds'
// set "timer" for time duration  otherwise set a "date" value

// timer string format is _number_UNIT where UNIT = 'd','h','m','s'  for Days, Hours, Minutes, Seconds
// ex : '3d 25m 6s'  = 3 days 0 hours 25 minutes, 6 seconds  (days = 0, 0 is defauls for all units)
// ex : '6s 3d 25m'  = the same, there is no order
// date format is JS Date format  see new Date( _STRING_ )
body {
  background-color: #f2f1ed;
  margin: 0;
}
.wrap {
  margin: 2em auto;
  height: 270px;
  width: 1500px; /*   be re-calculate on JS */
  border-radius: 1em;
  padding: 10px 5px 0 5px;
  box-shadow: 0px 0px 1px 1px rgba(170, 170, 170, 0.64);
}
a {
  text-decoration: none;
  color: #1a1a1a;
}
h1 {
  margin-bottom: 30px;
  text-align: center;
  font: 300 2.25em "Lato";
  text-transform: uppercase;
}
h1 strong {
  font-weight: 400;
  color: #ea4c4c;
}
h2 {
  margin-bottom: 80px;
  text-align: center;
  font: 300 0.7em "Lato";
  text-transform: uppercase;
}
h2 strong {
  font-weight: 400;
}

.countdown {
/*   width: 100%;  or be re-calculate on JS */
  margin: 0 auto;
  padding: 0 10px 10px 10px;
}
.countdown .bloc-time {
  float: left;
  margin-right: 45px;
  text-align: center;
}
.countdown .bloc-time:last-child {
  margin-right: 0;
}
.countdown .count-title {
  display: block;
  margin-bottom: 15px;
  font: normal 0.94em "Lato";
  color: #1a1a1a;
  text-transform: uppercase;
}
.countdown .figure {
  position: relative;
  float: left;
  height: 110px;
  width: 100px;
  margin-right: 10px;
  background-color: #fff;
  border-radius: 8px;
  -moz-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
  -webkit-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
  box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08);
}
.countdown .figure:last-child {
  margin-right: 0;
}
.countdown .figure > span {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  font: normal 5.94em/107px "Lato";
  font-weight: 700;
  color: #de4848;
}
.countdown .figure .top:after, .countdown .figure .bottom-back:after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.countdown .figure .top {
  z-index: 3;
  background-color: #f7f7f7;
  transform-origin: 50% 100%;
  -webkit-transform-origin: 50% 100%;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px;
  border-top-left-radius: 10px;
  -moz-border-radius-topright: 10px;
  -webkit-border-top-right-radius: 10px;
  border-top-right-radius: 10px;
  -moz-transform: perspective(200px);
  -ms-transform: perspective(200px);
  -webkit-transform: perspective(200px);
  transform: perspective(200px);
}
.countdown .figure .bottom {
  z-index: 1;
}
.countdown .figure .bottom:before {
  content: "";
  position: absolute;
  display: block;
  top: 0;
  left: 0;
  width: 100%;
  height: 50%;
  background-color: rgba(0, 0, 0, 0.02);
}
.countdown .figure .bottom-back {
  z-index: 2;
  top: 0;
  height: 50%;
  overflow: hidden;
  background-color: #f7f7f7;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px;
  border-top-left-radius: 10px;
  -moz-border-radius-topright: 10px;
  -webkit-border-top-right-radius: 10px;
  border-top-right-radius: 10px;
}
.countdown .figure .bottom-back span {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  margin: auto;
}
.countdown .figure .top, .countdown .figure .top-back {
  height: 50%;
  overflow: hidden;
  -moz-backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.countdown .figure .top-back {
  z-index: 4;
  bottom: 0;
  background-color: #fff;
  -webkit-transform-origin: 50% 0;
  transform-origin: 50% 0;
  -moz-transform: perspective(200px) rotateX(180deg);
  -ms-transform: perspective(200px) rotateX(180deg);
  -webkit-transform: perspective(200px) rotateX(180deg);
  transform: perspective(200px) rotateX(180deg);
  -moz-border-radius-bottomleft: 10px;
  -webkit-border-bottom-left-radius: 10px;
  border-bottom-left-radius: 10px;
  -moz-border-radius-bottomright: 10px;
  -webkit-border-bottom-right-radius: 10px;
  border-bottom-right-radius: 10px;
}
.countdown .figure .top-back span {
  position: absolute;
  top: -100%;
  left: 0;
  right: 0;
  margin: auto;
}
<link href='https://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>

<!-- no more HTML code -->

Build a Countdown Timer in Just 18 Lines of JavaScript, Sometimes, you're going to need to build a JavaScript countdown clock. You may Basic Clock: Count down to a Specific Date or Time. Here's a Display the clock on the page, and stop the clock when it reaches zero. This object allows you to call your function and get any of the calculated values. Free Countdown Timer for Your Website. Our free countdown timer is an accurate timer that you can use for your website or blog. It can help you count down to any special event, such as a birthday or anniversary. There are many ways for you personalize your own countdown timer, simply by filling out the gray form below on this page.


// Create Countdown
var Countdown = {

  // Backbone-like structure
  $el: $('.countdown'),

  // Params
  countdown_interval: null,
  total_seconds     : 0,

  // Initialize the countdown  
  init: function() {

    // DOM
        this.$ = {
        hours  : this.$el.find('.bloc-time.hours .figure'),
        minutes: this.$el.find('.bloc-time.min .figure'),
        seconds: this.$el.find('.bloc-time.sec .figure')
    };

    // Init countdown values
    this.values = {
          hours  : this.$.hours.parent().attr('data-init-value'),
        minutes: this.$.minutes.parent().attr('data-init-value'),
        seconds: this.$.seconds.parent().attr('data-init-value'),
    };

    // Initialize total seconds
    this.total_seconds = this.values.hours * 60 * 60 + (this.values.minutes * 60) + this.values.seconds;

    // Animate countdown to the end 
    this.count();    
  },

  count: function() {

    var that    = this,
        $hour_1 = this.$.hours.eq(0),
        $hour_2 = this.$.hours.eq(1),
        $min_1  = this.$.minutes.eq(0),
        $min_2  = this.$.minutes.eq(1),
        $sec_1  = this.$.seconds.eq(0),
        $sec_2  = this.$.seconds.eq(1);

        this.countdown_interval = setInterval(function() {

        if(that.total_seconds > 0) {

            --that.values.seconds;              

            if(that.values.minutes >= 0 && that.values.seconds < 0) {

                that.values.seconds = 59;
                --that.values.minutes;
            }

            if(that.values.hours >= 0 && that.values.minutes < 0) {

                that.values.minutes = 59;
                --that.values.hours;
            }

            // Update DOM values
            // Hours
            that.checkHour(that.values.hours, $hour_1, $hour_2);

            // Minutes
            that.checkHour(that.values.minutes, $min_1, $min_2);

            // Seconds
            that.checkHour(that.values.seconds, $sec_1, $sec_2);

            --that.total_seconds;
        }
        else {
            clearInterval(that.countdown_interval);
        }
    }, 1000);    
  },

  animateFigure: function($el, value) {

     var that         = this,
             $top         = $el.find('.top'),
         $bottom      = $el.find('.bottom'),
         $back_top    = $el.find('.top-back'),
         $back_bottom = $el.find('.bottom-back');

    // Before we begin, change the back value
    $back_top.find('span').html(value);

    // Also change the back bottom value
    $back_bottom.find('span').html(value);

    // Then animate
    TweenMax.to($top, 0.8, {
        rotationX           : '-180deg',
        transformPerspective: 300,
          ease                : Quart.easeOut,
        onComplete          : function() {

            $top.html(value);

            $bottom.html(value);

            TweenMax.set($top, { rotationX: 0 });
        }
    });

    TweenMax.to($back_top, 0.8, { 
        rotationX           : 0,
        transformPerspective: 300,
          ease                : Quart.easeOut, 
        clearProps          : 'all' 
    });    
  },

  checkHour: function(value, $el_1, $el_2) {

    var val_1       = value.toString().charAt(0),
        val_2       = value.toString().charAt(1),
        fig_1_value = $el_1.find('.top').html(),
        fig_2_value = $el_2.find('.top').html();

    if(value >= 10) {

        // Animate only if the figure has changed
        if(fig_1_value !== val_1) this.animateFigure($el_1, val_1);
        if(fig_2_value !== val_2) this.animateFigure($el_2, val_2);
    }
    else {

        // If we are under 10, replace first figure with 0
        if(fig_1_value !== '0') this.animateFigure($el_1, 0);
        if(fig_2_value !== val_1) this.animateFigure($el_2, val_1);
    }    
  }
};

function initializeCountdown ( $element ){
  let uniqueCountdown = $.extend( {}, Countdown );
  uniqueCountdown.$el = $element;

  uniqueCountdown.init();
}

$('.countdown').each( function(){
  initializeCountdown( $(this) );
});

I've changed the logic with the last function and its subsequent invocation. The method makes a copy of the Countdown to provide a unique this for each object. It then sets the $el it corresponds to before initializing. We then call this method for each of our countdown elements, and since the this is unique, each countdown will operate independently of each other and will allow for countdowns to have different starting times.

Talk:Countdown | Fandom Developers Wiki, My modified code here determines whether it should be sigular or plural (1 By '​script', are you referring to the html used to insert the countdown, or the JavaScript itself? remove the countdown; let it stay at zero; show alternate content There appears to be a bug if there are multiple countdowns on a page where an  It is simple to add additional countdowns. Near the bottom, simply use .add() to add more dates to your countdown. Where the first parameter is the date in the correct format (you can use the generator to create and format additional dates) and the second parameter is the id="" of the additional div where you will display the countdown.


JavaScript Countdown/Count-up Timer/Clock/Ticker Widget for Web , JavaScript Countdown/Count-up Timer/Clock/Ticker Widget for Web Pages You can also customize the display format, foreground and background colors of the code by using object wrapping to allow for multiple countdowns on one page. <script> // Set the date we're counting down to var countDownDate = new Date("Jan 5, 2021 15:37:25").getTime(); // Update the count down every 1 second var x = setInterval(function() { // Get today's date and time var now = new Date().getTime(); // Find the distance between now and the count down date var distance = countDownDate - now;


Countdown App by timeanddate.com, Why is the countdown off by 1 hour? If it looks How do I change the order of the countdowns? Tap Edit The Countdowns take up too much space on the overview page. How can I I am missing the timer functionality from the old version. Where Performance improvements for multiple image responsiveness; Bug fixes  Countdown to a Date or Create Evergreen Countdowns. Create a countdown that ends at a specific date or create per countdowns that are unique to each visitors. For example give each user 4 hours to complete an action.


‎Countdown Timer Plus on the Mac App Store, Download Countdown Timer Plus for macOS 10.11 or later and enjoy it on your Mac. To add unlimited number of countdowns and to use 3 different styles of So far this is the only app I have been able to find that will let you set multiple alarms Unlike other apps where all of the great features are barred from you by an  1. countdown.pl - The Perl script which does the calculation of the time until an event will occur. 2. README - The file that does all the explaining. 3. countdown.html - An example of ways to incorporate countdown.pl and use it properly. You will have to do some minimal configuration of the countdown.pl file. countdown.pl