A journey to writing vanilla web components

Part 3: Events

Thomas Juster
2 min readJul 8, 2020

If you come from the React world, it’s kind of the equivalent of callback props

Write a completely useless − yet experimental − component <events-demo />

The specs:

  • Emit the event 'change' using a button
  • Emit a custom event 'sayhello' using another button
  • Be able to use listeners shorthand .onchange and .onsayhello .
The component we are about to build

The template (HTML)

First, let’s start with our web component template:

<!-- index.html -->
<body>
<template id="events-demo-template">
<div>
<button id="dispatch-change">
Trigger change Event
</button>
</div>
<div>
<button id="dispatch-sayhello">
Trigger custom event "sayhello"
</button>
</div>
<style>…</style>
</template>

</body>

The component constructor

Now let’s see how we can dispatch those events using our buttons:

As always, let’s start with the boilerplate:

// events-demo.js
export class HTMLEventsDemoElement extends HTMLElement {
constructor () {
super();
const template = document.getElementById(
"events-demo-template"
);
if (!template) {
throw new Error("<events-demo /> template is not defined");
}
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));

}
}

Now that we are settled, let’s add methods to dispatch our events “change” and “sayhello”:

// events-demo.js
export class HTMLEventsDemoElement extends HTMLElement {
constructor () {…}
dispatchChange () {
this.dispatchEvent(new Event('change'));
}
dispatchSayHello (detail = '') {
const customEvent = new CustomEvent('sayhello', { detail });
this.dispatchEvent(customEvent);
if (this.onsayhello) this.onsayhello(customEvent);
}
}

And finally, let’s trigger those events when the user clicks on a button:

// events-demo.js
export class HTMLEventsDemo extends HTMLElement {
constructor () {

this.shadowRoot
.querySelector("button#dispatch-change")
.addEventListener("click", () => {
this.dispatchChange();
});
this.shadowRoot
.querySelector("button#dispatch-sayhello")
.addEventListener("click", () => {
this.dispatchSayHello("Hello from the other side…");
});
}

}

Aand we’re done !

Me, polishing that incredibly useless component.

Using our component

Demo of our pointless component

Now we can use our component <events-demo /> and add event listeners to it, using JS. Check out the demo:

Much useful, such wow.

--

--