I'm new to JavaScript, and does not understand the prototyping process very well. I am stuck with this problem:
I want to create a stopwatch that is prototype-based (for further enhancements). The stopwatch works on user interaction (start/stop) and shows elapsed time in seconds.
The elapsed time is calculated by storing the starting time in the instance property, and subtracting this value from the actual time.
My problem is that after the start function sets the starting time, it vanishes at the point when the update function is called (so the update function does not get the start value at all). After this, when the stop function is triggered, the stop function does not get the elapsed time value.
My guess is that the functions are not called on the instance but on the prototype.
Please help me understand the general situation with prototypes and instances in this code better, and help me find the problem and the solution. Thank you!
var StopWatch = function () {
this.startTime = 0;
this.elapsedTime = 0;
};
StopWatch.prototype.start = function () {
StopWatch.call(this);
this.startTime = now();
this.updateElapsedTime();
};
StopWatch.prototype.updateElapsedTime = function () {
StopWatch.call(this);
this.elapsedTime = now() - this.startTime;
this.triggerNextTimeUpdate();
};
StopWatch.prototype.triggerNextTimeUpdate = function () {
StopWatch.call(this);
this.timer = setTimeout(this.updateElapsedTime.bind(this), 1000);
};
StopWatch.prototype.stop = function () {
StopWatch.call(this);
clearTimeout(this.timer);
};
See the code snippet for the whole code:
/*
* JavaScript StopWatch for worklog time measurement
*/
//**************************************************
// Helpers
//**************************************************
var now = function () {
return Math.round(new Date().getTime() / 1000);
};
//**************************************************
// Stopwatch functionality
//**************************************************
var StopWatch = function () { // PROTOTYPE (class definition & constructor)
this.startTime = 0;
this.elapsedTime = 0;
};
StopWatch.prototype.createDivInstance = function () {
StopWatch.call(this);
var newDivInstance = document.body.appendChild(document.createElement("div"));
newDivInstance.className = "jssw";
newDivInstance.innerHTML = "" +
"<span class='elapsedTime'>" + this.elapsedTime + "</span><br>" +
"<span class='buttons'>" +
"\< <span id='start'>Start</span> | <span id='stop'>Stop</span> \>" +
"</span>";
var start = document.getElementById('start');
var stop = document.getElementById('stop');
start.addEventListener("click", this.start.bind(this));
stop.addEventListener("click", this.stop.bind(this));
};
StopWatch.prototype.start = function () {
StopWatch.call(this);
this.startTime = now();
this.updateElapsedTime();
};
StopWatch.prototype.updateElapsedTime = function () {
StopWatch.call(this);
this.elapsedTime = now() - this.startTime;
document.querySelector(".jssw span.elapsedTime").innerHTML = this.elapsedTime;
this.triggerNextTimeUpdate();
};
StopWatch.prototype.triggerNextTimeUpdate = function () {
StopWatch.call(this);
this.timer = setTimeout(this.updateElapsedTime.bind(this), 1000);
};
StopWatch.prototype.stop = function () {
StopWatch.call(this);
clearTimeout(this.timer);
};
var swInstance = new StopWatch();
swInstance.createDivInstance();
<html>
<head>
<title>How do javascript objects work?</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script></script>
</body>
</html>