Skip to content

Instantly share code, notes, and snippets.

@okikio
Last active June 20, 2024 20:56
Show Gist options
  • Save okikio/167247c82c2d5fdc16cec330f4819e0c to your computer and use it in GitHub Desktop.
Save okikio/167247c82c2d5fdc16cec330f4819e0c to your computer and use it in GitHub Desktop.
A way to keep event handler private, but still benefit from a constant event listener object, decreasing memory overhead and ensuring private fields stay private. Inspired by https://webreflection.medium.com/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38. Demo https://codepen.io/okikio/pen/QWRmdxm
export class Component {
/**
* For perf. reasons use a class to delagate event handlers,
* this lets us avoid binds and arrow functions which have memory overhead,
* in addition since it's always the same instance of the same class,
* so it's super easy to remove later on
*
* Based on https://webreflection.medium.com/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38
*/
static #eventhandlers = new WeakMap();
static #eventhandler = class PrivateEventHandler<T> {
#delegated: T;
constructor(delegated: T)
{ this.#delegated = delegated; }
handleEvent(event: Event)
{ (this.#delegated as any).#handleEvent(event); }
}
#el: HTMLElement | null;
constructor(el: HTMLElement | null) {
this.#el = el;
const eventhandler = new Component.#eventhandler(this);
Component.#eventhandlers.set(this, eventhandler);
this.#el?.addEventListener?.("click", eventhandler);
}
/**
* Called by the Private Event Handler
* @param evt
* @returns
*/
#handleEvent(evt: MouseEvent) {
console.log({
evt
})
}
}
new Component(document.querySelector('button'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment