I would like to create a custom event in JavaScript.
I have a WPF application with a WebBrowser inside, and a HTML page with JavaScript.
I work with a printe
I like using this EventDispatcher constructor method, which, using a dummy element, isolates the events so they will not be fired on any existing DOM element, nor the window or document.
I am using
CustomEventand notcreateEventbecause it's the newer approach. Read more here.
I like to wrap each native method with these names:
on, off, triggerfunction eventDispatcher(){
// Create a dummy DOM element, which is a local variable
var dummy = document.createTextNode('')
// Create custom wrappers with nicer names
return {
off(...args){
dummy.removeEventListener(...args)
return this
},
on(...args){
dummy.addEventListener(...args)
return this
},
trigger(eventName, data){
if( !eventName ) return
// if the event should be allowed to bubble,
// then "dummy" must be in the DOM
var e = new CustomEvent(eventName, {detail:data})
dummy.dispatchEvent(e)
return this
}
}
}
////////////////////////////////////
// initialize the event dispatcher by creating an instance in an isolated way
var myEventDispatcher = eventDispatcher();
////////////////////////////////////
// listen to a "foo" event
myEventDispatcher
.on('foo', e => console.log(e.type, e.detail) )
.on('bar', e => console.log(e.type, e.detail) )
////////////////////////////////////
// trigger a "foo" event with some data
myEventDispatcher
.trigger('foo', 123)
.trigger('bar', 987);
The above eventDispatcher could be integrated into another code, for example, a Constructor:
(for example some component)
function eventDispatcher(){
var dummy = document.createTextNode('')
return {
off(...args){
dummy.removeEventListener(...args)
return this
},
on(...args){
dummy.addEventListener(...args)
return this
},
trigger(eventName, data){
if( !eventName ) return
var e = new CustomEvent(eventName, {detail:data})
dummy.dispatchEvent(e)
return this
}
}
}
/////////////////////////////
// Some component:
var MyComponent = function(){
// merge `EventDispatcher` instance into "this" instance
Object.assign(this, eventDispatcher())
// set some default value
this.value = 1
}
MyComponent.prototype = {
set value(v){
this.trigger('change', v)
}
}
var comp = new MyComponent();
// bind a listener to "comp" (which itself is an instance of "MyComponent")
comp.on('change', e => console.log("Type:", e.type,", Value:", e.detail) )
// set some value
comp.value = 3;
See related answer to the question "Event Handler Namespace in Vanilla JavaScript"