I recommend you rewrite the code to avoid cluttering the global namespace. Although, I do have two followup questions on the code I post (but the code does work as is). I realized asking those questions here would constitute thread hijacking so I'm double posting the code and asking the questions elsewhere instead.
var Timer = (function(w, el, elid) {
var id = null;
var cycles = 5;
var p = {
setCycles : function(i) {
i = parseInt(i);
if (isNaN(i))
throw 'not a number';
if (i <= 0)
throw 'Out of range';
cycles = i;
// Question #1: Why is it not possible to use el directly here
el.html(cycles);
// while creating new jquery objects work fine
jQuery('#'+elid).html(cycles);
},
start : function(ms) {
ms = parseInt(ms);
if (isNaN(ms))
throw 'not a number';
if (ms <= 0)
throw 'Out of range';
if (id == null && cycles > 0) {
id = w.setInterval(this.cycle, ms);
}
},
stop : function() {
if (id != null) {
w.clearInterval(id);
id = null;
}
},
cycle : function() {
--cycles;
// Question #1 all over again
el.html(cycles);
jQuery('#'+elid).html(cycles);
if (cycles <= 0) {
// Question #2: Why doens't this.stop() work?
// Or perhaps I should ask why this is window here, while this above is Timer.
// And is there a workaround or better way to write the code?
Timer.stop();
}
}
}
jQuery(document).ready(function($) {
$('#setCycles').on('click', function(evt) {
p.setCycles($(evt.target).siblings('input').prop('value'));
});
$('#start').on('click', function(evt) {
p.start(1000);
});
$('#stop').on('click', function(evt) {
p.stop();
});
});
return p;
})(window, jQuery('#display'), 'display');
<div id="set">
<button type="button" id="setCycles">Set</button>
<input type="numeric" value="5">
</div>
<div id="toggle">
<div>
<button type="button" id="start">Start</button>
</div>
<div>
<button type="button" id="stop">Stop</button>
</div>
</div>
<div id="display">5</div>