helpers/event-helpers.js

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);
}
}
}