jquery-countdown
jquery-countdown copied to clipboard
don't work when use 2 or more countdow on 1 page
correct work only last of them i understand that problem is in code var digits = []; var intervals = []; but how to fix it ...
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 */ };
This fix doesn't work. The problem remains.
yesworld's fix works! Thanks!
Any suggestions how to fix it?
Analized what yesworld said, and fix really works! All plugin code should be inside
jQuery.fn.countdown = function(userOptions) {
....
};
Nothing should be outside.
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
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!
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);
};