Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

don't work when use 2 or more countdow on 1 page #22

Open
Priorko opened this issue Jul 22, 2014 · 8 comments
Open

don't work when use 2 or more countdow on 1 page #22

Priorko opened this issue Jul 22, 2014 · 8 comments

Comments

@Priorko
Copy link

Priorko commented Jul 22, 2014

correct work only last of them
i understand that problem is in code
var digits = [];
var intervals = [];
but how to fix it ...

@yesworld
Copy link

Quick fix it all outer functions to include in the plugin.

jQuery.fn.countdown = function(userOptions) {
var digits = [];
var intervals = [];
var createDigits = function(where, options) {}
var makeMovement = function(elem, steps, isForward, options) {}
var margin = function(elem, val) {}
var moveDigit = function(elem, options) {}
var parseRelativeDate = function(form, options) {}
var formatCompute = function(d, options) {}
var pad = function(x){return (1e15+""+x).slice(-2)};
/* Plugin code */
};

@ruskid
Copy link

ruskid commented Dec 22, 2014

This fix doesn't work. The problem remains.

@mailz
Copy link

mailz commented Apr 25, 2015

yesworld's fix works! Thanks!

@lexxful
Copy link

lexxful commented Jun 12, 2015

Any suggestions how to fix it?

@lexxful
Copy link

lexxful commented Jun 13, 2015

Analized what yesworld said, and fix really works!
All plugin code should be inside

jQuery.fn.countdown = function(userOptions) {
    ....
};

Nothing should be outside.

@fonziemedia
Copy link

Hi, this solution doesn't seem to be working for me, could you please provide more details. How are you starting your countdown? Should I be using a class to call the countdown or do I have to call it multiple times with multiple element ids? I've tried these approaches but none seemed to work for me. Any help would be appreciated, thanks

@fonziemedia
Copy link

Nevermind, I got it! It only works using multiple element ids and make sure you look for the "jQuery.fn.countdown = function(userOptions) {" and put all previous outer functions inside it. Thank you for this!

@MonteShaffer
Copy link

As mentioned in the comments, this does not do an .each( loop so each instance has to point to a unique id ... not a class ...
When pointing to a class, only the last one updates ...

works

<div id="clock-1"></div>
<div id="clock-2"></div>

with

<script>
      $(function(){
        $(".digits").countdown({
          image: "img/digits.png",
          format: "mm:ss",
          endTime: new Date(2013, 12, 2)
        });
      });
	  
	  
	  $(function(){
        $("#clock-1").countdown({
          image: "img/digits.png",
          format: "mm:ss",
          endTime: new Date(2013, 12, 2)
        });
      });
	  
	  
	  $(function(){
        $("#clock-2").countdown({
          image: "img/digits.png",
          format: "mm:ss",
          endTime: new Date(2013, 12, 2)
        });
      });
    </script>

does not work

<div class="digits"></div>
<div class="digits"></div>

Here is the explained JS description from above ...


jQuery.fn.countdown = function(userOptions) {
	var digits = [];
	var intervals = [];
	
	/*
 * jquery-countdown plugin
 *
 * Copyright (c) 2009 Martin Conte Mac Donell <[email protected]>
 * Dual licensed under the MIT and GPL licenses.
 * http://docs.jquery.com/License
 *
 */

// Draw digits in given container
var createDigits = function(where, options) {
  var counter = 0;
  // Iterate each startTime digit, if it is not a digit
  // we'll asume that it's a separator
  var mFirstPos, sFirstPos;
  // reset digits and intervals array.
  digits = [];
  intervals = [];

  for (var i = 0; i < options.startTime.length; i++) {
    if (parseInt(options.startTime[i]) >= 0) {
      elem = $('<div id="cnt_' + counter + '" class="cntDigit" />').css({
	height: options.digitHeight,
	float: 'left',
	background: 'url(\'' + options.image + '\')',
	width: options.digitWidth
      });

      elem.current = parseInt(options.startTime[i]);
      digits.push(elem);

      margin(counter, -elem.current * options.digitHeight * options.digitImages);

      if (options.continuous === true) {
	digits[counter]._max = function() { return 9; };
      } else {
	// Add max digits, for example, first digit of minutes (mm) has
	// a max of 5. Conditional max is used when the left digit has reach
	// the max. For example second "hours" digit has a conditional max of 4
	switch (options.format[i]) {
	  case 'h':
	    digits[counter]._max = function(pos, isStart) {
	      if (pos % 2 == 0)
		return 2;
	      else
		return (isStart) ? 3: 9;
	    };
	    break;
	  case 'd':
	    digits[counter]._max = function() { return 9; };
	    break;
	  case 'm':
	    digits[counter]._max = function(pos) {
	      if(!mFirstPos) { mFirstPos = pos; } 
	      return pos == mFirstPos ? 9 : 5;
	    };
	    break;
	  case 's':
	    digits[counter]._max = function(pos) {
	      if(!sFirstPos) { sFirstPos = pos; } 
	      return pos == sFirstPos ? 9 : 5;
	    };
	}
      }

      counter += 1;
    } else {
      elem = $('<div class="cntSeparator"/>').css({float: 'left'})
					     .text(options.startTime[i]);
    }
    where.append(elem)
  }
};

var makeMovement = function(elem, steps, isForward, options) {
  // Stop any other movement over the same digit.
  if (intervals[elem])
    window.clearInterval(intervals[elem]);

  // Move to the initial position (We force that because in chrome
  // there are some scenarios where digits lost sync)
  var initialPos = -(options.digitHeight * options.digitImages *
		     digits[elem].current);
  margin(elem, initialPos);
  digits[elem].current = digits[elem].current + ((isForward) ? steps: -steps);

  var x = 0;
  intervals[elem] = setInterval(function() {
    if (x++ === options.digitImages * steps) {
      window.clearInterval(intervals[elem]);
      delete intervals[elem];
      return;
    }

    var diff = isForward ? -options.digitHeight: options.digitHeight;
    margin(elem, initialPos + (x * diff));
  }, options.stepTime / steps);
};

// Set or get element margin
var margin = function(elem, val) {
  if (val !== undefined) {
    digits[elem].margin = val;
    return digits[elem].css({'backgroundPosition': '0 ' + val + 'px'});
  }

  return digits[elem].margin || 0;
};


// Makes the movement. This is done by "digitImages" steps.
var moveDigit = function(elem, options) {
  if (digits[elem].current == 0) {
    // Is there still time left?
    if (elem > 0) {
      var isStart = (digits[elem - 1].current == 0);

      makeMovement(elem, digits[elem]._max(elem, isStart), true, options);
      moveDigit(elem - 1, options);
    } else { // That condition means that we reach the end! 00:00.
      for (var i = 0; i < digits.length; i++) {
	clearInterval(intervals[i]);
	clearInterval(intervals.main);
	margin(i, 0);
      }
      options.timerEnd();
    }
    return;
  }
  makeMovement(elem, 1, false, options);
};



// parses a date of the form hh:mm:ss, for example, where
// ... precision is the same as the format.
var parseRelativeDate = function(form, options) {
  // give the date the values of now by default
  var now = new Date();
  var d = now.getDate();
  var m = now.getMonth() + 1;
  var y = now.getFullYear();
  var h = now.getHours(), mm, s;

  // read in components and render based on format
  var format = options.format;
  var parts = form.split(':');
  if( format.indexOf('dd') == 0 ) {
      d = parts[0];
      parts = parts.slice(1);
      format = format.substr(3);
  }
  if( format.indexOf('hh') == 0 ) {
      h = parts[0];
      parts = parts.slice(1);
      format = format.substr(3);
  }
  if( format.indexOf('mm') == 0 ) {
      mm = parts[0];
      parts = parts.slice(1);
      format = format.substr(3);
  }
  if( format.indexOf('ss') == 0 ) {
      s = parts[0];
      parts = parts.slice(1);
      format = format.substr(3);
  }
  // return our constructed date object
  return new Date([m, d, y].join('/') + ' ' + [h, mm, s].map(pad).join(':') + ' GMT-0900');
};


// convert a date object to the format specified
var formatCompute = function(d, options) {
      var format = options.format;
      var parse = {
	d: Math.floor( ( d - new Date( d.getFullYear(), 0, 1 ) ) / ( 1000 * 60 * 60 * 24 ) ),
	h: d.getUTCHours(),
	m: d.getUTCMinutes(),
	s: d.getUTCSeconds()
      };
      return format.replace(/(dd|hh|mm|ss)/g, function($0, form) {
	      return pad(parse[form[0]]);
      });
};

// add leading zeros
var pad = function(x){return (1e15+""+x).slice(-2)};


var start = function (element) {
	if (element.attr('started') != 'true') {	
		element.attr('started', true)
		intervals.main = setInterval(function () {
				moveDigit(digits.length - 1, element.data('options'));
			},
			1000);
	}
};
	
	
  // Default options
  var options = {
    stepTime: 60,
    // startTime and format MUST follow the same format.
    // also you cannot specify a format unordered (e.g. hh:ss:mm is wrong)
    format: "dd:hh:mm:ss",
    startTime: "01:12:32:55",
    digitImages: 6,
    digitWidth: 67,
    digitHeight: 90,
    timerEnd: function(){},
    image: "digits.png",
    continuous: false,
	start: true
  };
  $.extend(options, userOptions);

  // if an endTime is provided...
  if( userOptions.endTime ) {
    // calculate the difference between endTime and present time
    var endDate = userOptions.endTime instanceof Date ? userOptions.endTime : parseRelativeDate(userOptions.endTime, options);
    var diff = endDate.getTime() - (new Date()).getTime();
  	// and set that as the startTime
    userOptions.startTime = formatCompute(new Date(diff), options);
    delete userOptions.endTime;
  }
  $.extend(options, userOptions);
  if (this.length) {
    clearInterval(intervals.main);
    createDigits(this, options);
	this.data('options', options);
	if (options.start === true) {
		start(this);
	}
  }
};

// start the counter
jQuery.fn.start = function () {
	start(this);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants