msmith1114
msmith1114

Reputation: 3231

ES6 Classes/Object oriented and Event Handlers

I've been learning the ins and outs of JavaScript and Object Oriented/Functional programming instead of writing hacky imperative code that while works....just is ugly and honestly not efficient.

I was re-writing a tic-tac-toe game and am using Classes to implement the "Board" functions (Updating the board/checking tiles/etc...)

and I realized.....where on earth should I be putting Event listeners (for buttons/tiles/etc...) in the page. I usually just put jquery .click functions in the document.ready scope, but that doesn't seem right.

When I create a class with new would event listeners get attached or "readied"....I guess maybe I mis-understand how listeners work. And if they would work within a class as functions/methods? Or if it even makes sense to attach them there.

For instance here is my base class right now (it's literally just set up so it's like bare minimum.

"use strict";

class Board
{
   constructor(playerIcon,compIcon) { 
        this.playerIcon = playerIcon;
        this.compIcon = compIcon;
});
    }

    getTileContents(tile){
      return $("#tile-" + tile).text()
    }

    tileIsEmpty(tile){
        console.log($("#tile-" + tile).text())
      if($("#tile-" + tile).text() != 'X' || $("#tile-" + tile).text() != 'Y')
        return true
      else
        return false
    }  
}

let board = new Board('X','Y');

I thought maybe attaching the event listeners in the constructor would work? Since the constructor will be instantiated when new is called at least correct?

Maybe it's just my misunderstand of how event handlers are handled or "bound" exactly?

edit: Here is my pitiful tic-tac-toe so far for reference: http://codepen.io/msmith1114/pen/qmNevg

(This is what im talking about in regards to the board)

Upvotes: 0

Views: 4770

Answers (2)

Robert Jackson
Robert Jackson

Reputation: 39

this.domElement.addEventListener('click', this.handler.bind(this));

When you do this you can't remove the event handler so each time the code is used more and more even handlers are added, eventually filling memory, slowing down the page Javascript is a mess and needs a replacement badly.

Upvotes: 2

jwoos
jwoos

Reputation: 149

JavaScript events are bound to the document object model (DOM) and aren't bound to any arbitrary object you might make.

https://developer.mozilla.org/en-US/docs/Web/API/Event

The Event interface represents any event which takes place in the DOM; some are user-generated (such as mouse or keyboard events), while others are generated by APIs (such as events that indicate an animation has finished running, a video has been paused, and so forth).

So knowing that, we'd want to have some sort of DOM element in your class. It makes sense to connect your class which represents a physical object to the actual element - the class is just another presentation of the physical state of the DOM. Yes, you are correct that any code placed in the constructor will be executed - including any addition of event handlers.

If you wanted to create listeners as methods on the class you'd do something like:

class {
     constructor() {
         this.domElement.addEventListener('click', this.handler.bind(this));
     }

     handler() {
         this.hello();
     }

     hello() {
     }
}

It's crucial that you remember that the this scope has to be fixed via passing in a bound function call since it loses all context when passed in as a listener. The binding is not necessary if in the above code you were to not use any methods of the class, and it just becomes this.domElement.addEventListener('click', this.handler);.

This is obviously not the only way to add the handler but seems to me the more sane way when dealing with classes that represent the DOM.

Upvotes: 3

Related Questions