New Jul 27, 2024

Notes on handling events in Web Components

More Front-end Bloggers All from Ryan Mulligan View Notes on handling events in Web Components on ryanmulligan.dev

My click-spark web component was a fun, silly project at best. Yet I've seen it's had some love since being shared. So why not publish it as an npm package? No better time than the present, some say.

I had done a major refactor before publishing, the most notable was that the spark would now be contained to the custom element's parent node. After announcing the updates in a Mastodon post, I soon received a PR with some quality feedback including a more advantageous way to handle the parent click event using the handleEvent() method.

The click-spark click

Let's dive into a "before and after" for handling the click event on this component.

In both examples, notice that the parent node is being stored in a variable when connectedCallback runs. This ensures that the click event is properly removed from the parent since it's not available by the time disconnectedCallback is invoked as FND's comment explains.

In the "before" approach, the event handler is stored in a variable so that it's cleared from the parent node whenever the click-spark element is removed from the DOM.

constructor() {
  this.clickEvent = this.handleClick.bind(this);
}

connectedCallback() { this._parent = this.parentNode; this._parent.addEventListener("click", this.clickEvent); }

disconnectedCallback() { this._parent.removeEventListener("click", this.clickEvent); delete this._parent; }

handleClick() { // Run code on click }

Switching to handleEvent() removes the need to store the event handler. Passing this into the event listener will run the component's handleEvent() method every time we click.

constructor() {
  // No longer need to store the callback
}

connectedCallback() { this._parent = this.parentNode; this._parent.addEventListener("click", this); }

disconnectedCallback() { this._parent.removeEventListener("click", this); delete this._parent; }

handleEvent(e) { // Run code on click }

Helpful resources

Chris Ferdinandi's article, The handleEvent() method is the absolute best way to handle events in Web Components is an excellent read on why handleEvent() is a top choice for architecting event listeners in Web Components. He also shares insight from Andrea Giammarchi's DOM handleEvent: a cross-platform standard since year 2000 article which contains solid techniques for handling multiple event types.

Rather than me regurgitating, I recommend jumping into both of those articles to get a proper grasp on handleEvent().

Updated on July 29th, 2024 — FND published Garbage Collection for Event Listeners about event listener cleanup after an element is removed from the DOM. The included demo is a nice touch. One interesting footnote that stood out to me: moving the element to a new location in the DOM will invoke disconnectedCallback before invoking connectedCallback again.

Scroll to top