A lot of times when writing things you may want want to react to certain events on your page.
We do this all the time with builtin ones like click
or keydown
But we can also make our own custom events and have the browser handle all the work for us! Since it's part of the DOM API we get free event code without installing another lib or rolling our own buggy version.
CustomEvent
is what we will be using. We'll wrap it a little to make it a bit neater to use as well.
Making a custom event
It's pretty simple
const event = new CustomEvent("myevent", {details: {some: "data"}});
document.dispatchEvent(event);
Notice we had to put our own custom data in the details
key of the event. This is just a quirk of how they work.
Listening for a custom event
function eventHandler(event){
const data = event.details.data;
console.lo(data);
}
document.addEventListener("myevent", eventHandler)
Stopping listening
document.removeEventListener("myevent", eventHandler);
Pretty easy stuff.
What's great is, we can also dispatch the event on an element so it doesn't bubble up to the dom. Keeping our code event more modularized. Just replace document
with another element you have.
A little wrapper.
Because it's a little bit cumbersome to have to write all that everytime you want to use an event. Let's wrap it just a little.
function publish(eventName, data){
const event = new CustomEvent(eventName, {details: data});
document.dispatchEvent(event);
}
const events = [];
function subscribe(eventName, cb){
const wrapper = function(event){
cb(event.details);
}
document.addEventListener(eventName, wrapper);
events.push({
cb, wrapper, eventName
})
}
function unsubscribe(eventName, cb){
events.forEach((event)=>{
if(event.eventName === eventName && cb === event.cb){
document.removeEventListener(eventName, event.wrapper);
}
})
}
export {subscribe, unsubscribe, publish};
Usage
function eventHandler(data){
console.log(data);
}
subscribe("myEvent", eventHandler))
publish("myEvent", {some: "data"});
unsubscribe("myEvent", eventHandler);
Et voilà
If you like my stuff please check out my site https://dropconfig.com
Top comments (7)
Thanks Clay for the refresher. In the example for event listening you have
console.lo
rather thenconsole.log
. I like the pub/sub example and could be packaged into a tiny library.Do you use this as cross components communication? Example trigger a function in a sibling component?
Sure. That's a solid use case.
Thanks for your reply Clay.
I try to keep it top-down but I’ve faced a couple of situations where this pub/sub using the native event bubbling would come in real handy. Didn’t reach for it yet though.
This is awesome, I had no idea. Thanks!
Wow, amazing! Never heard of this thing,plz don't tease me, I'm just a little newb 😂 thanks so much for sharing this 🤗
Really cool! I don't know why I haven't seen this before!