0

SOLUTION: I didn't bind the stopHandler to the instance inside the constructor.


I defined a class and used it to make the event handler functions and things work different from what I expected.

My class works to render the view of time. Inside the instance of the class, each data preperties retain values for time (hour, minute, second, etc) and methods are event handlers.

There are only two buttons; with id of start and stop, and each of the linked to startHandler and stopHandler.

To make it iterate, I used setInterval and clearInterval, so it shows the current time in real time. To stop showing the time, I have to delete the setHandler, so I saved the reference for setInterval and used it with clearInterval in stopHandler method.

Here are codes below:

class Timer {
 constructor () {
  this.now = 0
  this.isDayOrNight = ""
  this.hours = 0
  this.minutes = 9
  this.seconds = 0
  this.milliseconds = 0
  this.view = ""

  this.setHandler = this.setHandler.bind(this)
  this.startHandler = this.startHandler.bind(this)
  this.intervalRef
 }

 setHandler() {
  this.now = new Date()
  this.hours = this.now.getHours()
  this.isDayOrNight = (this.hours >= 12) ? "PM" : "AM"
  this.minutes = this.now.getMinutes()
  this.seconds = this.now.getSeconds()
  this.milliseconds = this.now.getMilliseconds()

  this.view = "<p>The time right now: "  + this.isDayOrNight + " " + this.hours + " : " + this.minutes + " : " + this.seconds + " : " + this.milliseconds + "</p>"
  document.getElementById("view").innerHTML = this.view
 }

 startHandler() {
  console.dir(event)
  if (this.view !== "") {
   // clearInterval(this.intervalRef)
   // this.intervalRef = setInterval(this.setHandler, 100)
  }
  else {
   this.intervalRef = setInterval(this.setHandler, 100)
  }
  console.log(this)
  // Timer {now: 0, isDayOrNight: "", hours: 0, minutes: 9, seconds: 0, …}
  console.log(this.intervalRef)
 }

 stopHandler() {
  console.dir(event)
  console.log(this)
  // <button id="stop">STOP</button>
  console.log(this.intervalRef)
  // clearInterval(this.intervalRef)
 }
}

let timer = new Timer()
document.getElementById("start").addEventListener("click", timer.startHandler)
document.getElementById("stop").addEventListener("click", timer.stopHandler)
<!doctype html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Default HTML template</title>
 </head>

 <body>
  <div id="view"></div>
  <button id="start">START</button>
  <button id="stop">STOP</button>
  <script src="./script.js"></script>
 </body>
</html>

At this point problem occurs.

I expected the this inside the stopHandler will point to the instance that I made (new Timer() ), but it seems this this points to the element at which the "click" event occured. I could find out this by looking at the console window.

But on the other hand the this inside the startHandler points to the instance that I made, which is as I expected.

Is this okay situation? How do these this bind to different things?

cadenzah
  • 928
  • 3
  • 10
  • 23

0 Answers0