57 lines
1.9 KiB
JavaScript
57 lines
1.9 KiB
JavaScript
|
/**
|
||
|
* Add an event listener bound to the context of the superClass.
|
||
|
*
|
||
|
* @param {HTMLElement} node Element to attach the event listener to.
|
||
|
* @param {String} eventName Name of the event.
|
||
|
* @param {String} cbName Name of the handler.
|
||
|
*/
|
||
|
export const EventHelpers = function(superClass) {
|
||
|
return class extends superClass {
|
||
|
listen(node, eventName, cbName) {
|
||
|
this.__boundEventListeners = this.__boundEventListeners || new WeakMap();
|
||
|
const boundListener = this[cbName].bind(this);
|
||
|
const eventKey = `${eventName}_${cbName}`;
|
||
|
let listeners = this.__boundEventListeners.get(node);
|
||
|
|
||
|
// If there is already a handler for the event assigned we stop here.
|
||
|
if (listeners && typeof listeners[eventKey] === 'function') return;
|
||
|
|
||
|
if (!listeners) {
|
||
|
listeners = {};
|
||
|
}
|
||
|
|
||
|
listeners[eventKey] = boundListener;
|
||
|
this.__boundEventListeners.set(node, listeners);
|
||
|
node.addEventListener(eventName, boundListener);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Remove an event listener bound to the context of the superClass.
|
||
|
*
|
||
|
* @param {HTMLElement} node Element to attach the event listener to.
|
||
|
* @param {String} eventName Name of the event.
|
||
|
* @param {String} cbName Name of the handler.
|
||
|
*/
|
||
|
unlisten(node, eventName, cbName) {
|
||
|
this.__boundEventListeners = this.__boundEventListeners || new WeakMap();
|
||
|
const listeners = this.__boundEventListeners.get(node);
|
||
|
const eventKey = `${eventName}_${cbName}`;
|
||
|
|
||
|
if (listeners && typeof listeners[eventKey]) {
|
||
|
node.removeEventListener(eventName, listeners[eventKey]);
|
||
|
listeners[eventKey] = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
once(node, eventName, cbName) {
|
||
|
const wrappedCbName = `__onceCb__${cbName}`;
|
||
|
|
||
|
this[wrappedCbName] = (...args) => {
|
||
|
this[cbName](...args);
|
||
|
this.unlisten(node, eventName, wrappedCbName);
|
||
|
};
|
||
|
|
||
|
this.listen(node, eventName, wrappedCbName);
|
||
|
}
|
||
|
}
|
||
|
}
|