Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That's the fun part, because here you can code your event handling to read something more like a state machine. Here's a quick example in bogus code, adding and removing event listeners as we go along (and without keeping reference to all the callback functions):

  class ElementDragger {
    constructor(elm) {
      elm.addEventListener('mousedown', this);
    }
    handleEvent(e) {
      const elm = e.target;
      switch(e.type) {
        case 'mousedown':
          elm.removeEventListener('mousedown', this).
          elm.addEventListener('mousemove', this);
          elm.addEventListener('mouseup', this);
          break;
        case 'mousemove':
          elm.style.left = e.clientX + 'px';
          break;
        case 'mouseup':
          elm.removeEventListener('mousedown', this);
          elm.removeEventListener('mouseup', this);
          elm.addEventListener('mousedown', this);
          break;
      }
    }
  }


That seems complicated, fragile, and bad for performance in a DOM. Event bindings are slow (or at least, used to be).

I don't know the purpose unbinding mousedown on mousedown - it only fires once per mousedown doesn't it?

Why not just stick with `elm.addEventListener('mousedown', this.handleMouseDown.bind(this))`? Where's the benefit other than making things more verbose?


Bind is less performant, because bind creates a new function with new context. At the framework level, bind is avoided at all costs. @wiredearp's approach is correct, because it only adds a single event listener, everything else is conditional.


If you think the above code has bad performance because "event bindings are slow" then your preferred form using `bind` is going to have all of that and more; it sidesteps nothing (except extremely fast switch case matching) and only adds overhead, both in runtime and memory costs.

> Where's the benefit other than making things more verbose?

To be clear what you're asking, are you saying that:

    elm.addEventListener('mousedown', this);
... is more verbose than:

    elm.addEventListener('mousedown', this.handleMouseDown.bind(this))


If you plan to remove that event listener later on, you would need to go full verbose.

  this._callback = this.handleMouseDown.bind(this);
  elm.addEventListener('mousedown', this._callback);
  elm.removeEventListener('mousedown', this._callback);
  this._callback = null;
Compared to:

  elm.addEventListener('mousedown', this);
  elm.removeEventListener('mousedown', this);
  
@richthegeek I removed that event listener in my example to illustrate how easy it is, there was otherwise no good reason for it.


No, that a switch statement is more verbose than a single function.

Switch statements in OOP are a sign that something is wrong.


Switch statements are fine for simple tasks like the one in the example, especially earlier in a project where you do not know what you need in the future. You can always switch it to the correct pattern in version 2 as that way its better understood what hidden needs the code in question has, thus making it easy to pick a good OOP patern to replace it.

Then again, my jugment might be colored by working on codebases that are >21 years old.


It's however easy to read and that feels good if not right, since the common solutions to this imagined problem require substantial mental overhead as seen on https://hackernoon.com/rethinking-javascript-eliminate-the-s.... To promote "single functions" we could:

  handleEvent(e) {
    this[e.type](e, e.target);
  }
  mousemove(e, elm) {
    elm.style.left = e.clientX + 'px';
  }
... but then the discussion would almost certainly revolve around this questionable decision instead of the original topic.


> No, that a switch statement is more verbose than a single function.

You're vacillating and applying an inconsistent standard. The switch statement is used where multiple listeners are being attached, therefore it wouldn't work with your "single function". You'd need multiple functions.

Give any example passing functions directly as the callback to `addEventListener` to demonstrate your case, please. The equivalent version that simply implements DOMEventListener will be less verbose, be lighter on resources (both with memory use and with runtime), and have no need for any this-binding workaround weirdness.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: