I have a Stopwatch that has two problems.
In the code, there is a class with several methods, the currentWatch class is supposed to return a time (milliseconds, seconds, minutes).
- The first is that there is a millisecond NaN and I don't know how to fix it.
- And the second I want when I click the start (after the stop) from the continuation of that.
typescript code :
class StopWatch {
private duration: number;
private status: string;
private currentTime: any;
private domRef: HTMLElement | null;
private interval: any;
private milliSecond: number;
private second:number;
private minute: number;
constructor(wrapper: string) {
this.duration = 0;
this.milliSecond = 0;
this.second = 0;
this.minute = 0;
this.domRef = document.getElementById(wrapper);
this.status = 'stopped';
if (!this.domRef) throw new Error('Does not exist');
this.render();
}
private render() {
this.domRef!.append(
createBtn('start', () => this.start()),
createBtn('stop', () => this.stop()),
createBtn('reset', () => this.reset()),
)
}
private start() {
if(this.status === 'started') throw new Error('already started');
this.currentTime = Date.now();
this.status = 'started';
const p = document.createElement("p");
p.id = "p";
document.body.appendChild(p);
this.interval = setInterval(() => {
this.minute, this.second, this.milliSecond = Number(this.currentWatch());
document.getElementById("p")!.innerHTML = `${this.minute} : ${this.second} : ${this.milliSecond}`;
}, 100);
}
private currentWatch() {
this.duration = Date.now() - this.currentTime;
if(this.status === 'stopped') this.stop();
let minutes = Math.floor(this.duration / (1000 * 60));
let seconds = Math.floor((this.duration % (1000 * 60)) / 1000);
let milliSeconds = Math.floor(this.duration % 1000);
this.minute = minutes;
this.second = seconds;
this.milliSecond = milliSeconds;
return [this.minute, this.second, this.milliSecond];
}
stop() {
clearInterval(this.interval);
if(this.status === 'stopped') throw new Error('already stopped');
this.duration = Date.now() - this.currentTime this.duration;
this.status = 'stopped';
return this.duration;
}
reset(){
if(this.status === 'started') this.stop();
this.duration = 0;
document.getElementById("p")!.innerHTML = this.duration.toString();
}
}
function createBtn(name: string, listener: () => void) {
const startBtn = document.createElement('button');
startBtn.innerText = name;
startBtn.addEventListener('click', listener);
return startBtn;
}
(function() {
const btns = document.getElementsByClassName('add-btn');
btns[0].addEventListener('click', () => {
new StopWatch(btns[0].getAttribute('data-idw') as string);
});
})();
I put the compiled code of TypeScript to show the result.
var StopWatch = /** @class */ (function () {
function StopWatch(wrapper) {
this.duration = 0;
this.milliSecond = 0;
this.second = 0;
this.minute = 0;
this.domRef = document.getElementById(wrapper);
this.status = 'stopped';
if (!this.domRef)
throw new Error('Does not exist');
this.render();
}
StopWatch.prototype.render = function () {
var _this = this;
this.domRef.append(createBtn('start', function () { return _this.start(); }), createBtn('stop', function () { return _this.stop(); }), createBtn('reset', function () { return _this.reset(); }));
};
StopWatch.prototype.start = function () {
var _this = this;
if (this.status === 'started')
throw new Error('already started');
this.currentTime = Date.now();
this.status = 'started';
var p = document.createElement("p");
p.id = "p";
document.body.appendChild(p);
this.interval = setInterval(function () {
_this.minute, _this.second, _this.milliSecond = Number(_this.currentWatch());
document.getElementById("p").innerHTML = "".concat(_this.minute, " : ").concat(_this.second, " : ").concat(_this.milliSecond);
}, 100);
};
StopWatch.prototype.currentWatch = function () {
this.duration = Date.now() - this.currentTime;
if (this.status === 'stopped')
this.stop();
var minutes = Math.floor(this.duration / (1000 * 60));
var seconds = Math.floor((this.duration % (1000 * 60)) / 1000);
var milliSeconds = Math.floor(this.duration % 1000);
this.minute = minutes;
this.second = seconds;
this.milliSecond = milliSeconds;
return [this.minute, this.second, this.milliSecond];
};
StopWatch.prototype.stop = function () {
clearInterval(this.interval);
if (this.status === 'stopped')
throw new Error('already stopped');
this.duration = Date.now() - this.currentTime this.duration;
this.status = 'stopped';
return this.duration;
};
StopWatch.prototype.reset = function () {
if (this.status === 'started')
this.stop();
this.duration = 0;
document.getElementById("p").innerHTML = this.duration.toString();
};
return StopWatch;
}());
function createBtn(name, listener) {
var startBtn = document.createElement('button');
startBtn.innerText = name;
startBtn.addEventListener('click', listener);
return startBtn;
}
(function () {
var btns = document.getElementsByClassName('add-btn');
btns[0].addEventListener('click', function () {
new StopWatch(btns[0].getAttribute('data-idw'));
});
})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>StopWatch</title>
</head>
<body>
<button data-idw="qwe">Add new StopWatch</button>
<div id="qwe"></div>
<script src="main.js"></script>
</body>
</html>
CodePudding user response:
It looks like your currentWatch
function is returning an array.
In your start
function, you create a new Number
with the value returned from currentWatch
.
Number accepts only a single input.
Perhaps, refactor your start
method to something like this
this.interval = setInterval(() => {
this.currentWatch();
document.getElementById("p")!.innerHTML = `${this.minute} : ${this.second} : ${this.milliSecond}`;
}, 100);
CodePudding user response:
You have to set the variables from the array in start like this:
[_this.minute, _this.second, _this.milliSecond] = _this.currentWatch();
Since currentWatch()
returns an array.
Of course there are also other ways to do that, but this one might be closest to your original code.