Notes on handling events in Web Components
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.