This is the DOM events API.
The package modules are:
can-dom-eventswhich replacescan-util/dom/eventscan-dom-events/event/make-customfor standardizing custom eventscan-dom-events/event/make-nativefor standardizing native eventscan-dom-events/event/make-compatfor compatibility withcan-util/dom/eventscan-dom-events/make-registryfor creating event registries
Topics:
- Standalone events
- Package custom events
- Unified native events
- Registered events
- Generic registries
- Global registry
- Documentation story
Allows events without the need for a registry. Example:
import myCustomEvent from 'can-event-my'
const el // HTML element
const removeListener = myCustomEvent.addListener(el, () => {
// called when the custom event triggers
})
removeListener() // removes the handler from the custom eventCustom events that can be their own packages.
The prefix is can-event- such as in can-event-radiochange.
The make-custom module makes custom events:
// my-event.js
const makeCustom = require('can-dom-events/event/make-custom')
module.exports = makeCustom('my-event', function addListener () {
/* EventTarget as this */
/* EventTarget.addEventListener() arguments as arguments */
// add listener ...
return function removeListener () {
// remove listener ...
}
})To support can-util/dom/events overriding behavior, pass the result of
make-custom to make-compat which returns a compatibility layer which accepts
an can-util/dom/events/events object to override:
// my-event-compat.js
const myEvent = require('./my-event')
const makeCompat = require('can-dom-events/event/make-compat')
module.exports = makeCompat(myEvent)// my-old-can-util-app.js
const domEvents = require('can-util/dom/events/events')
const myEvent = require('./my-event-compat')
const removeEvent = myEvent.override(domEvents)
removeEvent() // un-does the overridingFor consistency, native events can adapt to the subscription-disposal pattern.
This utility lives in the can-dom-events/event/make-native module.
// can-dom-events/event/make-native.js
const makeCustom = require('./make-native')
module.exports = function makeNativeEvent (eventName) {
return makeCustom(eventName, function addListener () {
this.addEventListener.apply(this, arguments)
return () => {
this.removeListener.apply(this, arguments)
}
})
}const makeNative = require('can-dom-events/event/make-native')
const clickEvent = makeNative('click')
const cleanupClick = clickEvent.addListener(el, () => {
// called when the click event triggers
})
cleanupClick() // removes the handler from the click eventThe main can-dom-events module calls make-native for unknown events when
called with addListener, returning a disposal function as custom events do.
Registries group custom events.
The can-dom-events/make-registry module creates registries.
// my-registry.js
const makeRegistry = require('can-dom-events/make-registry')
/*
NOTE: implementors decide where to store registry data
Some possible implementations: inside of a DefineMap prop, DOM data, or global map
*/
const sharedStorage = {}
const storageSolution = {
get (eventName) {
return sharedStorage[eventName]
},
set (eventName, event) {
sharedStorage[eventName] = event
},
remove (eventName) {
delete sharedStorage[eventName]
}
}
module.exports = makeRegistry(storageSolution)// can-dom-events/make-registry.js
module.exports = function makeRegistry (storage) {
return {
addEvent (eventName, customEvent) {
const self = this
eventName = eventName || customEvent.defaultEventName
const existingEvent = storage.get(eventName)
if (existingEvent) {
// throw error; no duplicate events allowed
}
storage.set(eventName, customEvent)
return function removeEvent () {
storage.remove(eventName)
}
},
addEventListener (eventName) {
const customEvent = storage.get(eventName)
if (customEvent) {
return customEvent.addListener.apply(this, arguments)
}
}
}
}Adding events to a registry:
import myCustomEvent from 'can-event-my'
import myRegistry from './my-event-registry'
const removeEvent = myRegistry.addEvent('my-event', myCustomEvent)
const removeListener = myRegistry.addEventListener.call(el, 'my-event', () => {
// called when the my-event triggers
})
removeListener() // remove listener from event
removeEvent() // remove custom event from registryThe custom event .addGlobally() method will add an event to the global registry.
const removeGlobally = require('can-event-my').addGlobally()
// ^ add custom event to global registry
removeGlobally() // remove custom event from global registryThe global registry used by the core can-dom-events module is not exposed.
End users of can-dom-events use can-dom-events directly along with the
custom events they choose to use.
All other packages are for implementors.
The make-registry module is for can-component and other packages which want
to support scoped events.
The event/make-{custom|native|compat} modules are for custom event package
authors to extend. This will give us much greater flexibility in the future to
make sweeping interface changes to all event types at once as they all extend
from a common base.
The can-util/dom/events split into packages, get marked as deprecated in util,
and get removed in can-util's 4.0. The breaking up of packages can happen in
pieces thanks to the can-dom-events/event/make-compat layer.