@jjwesterkamp/event-delegation
Version:
Event delegation for browser DOM events. Flexible, cross-browser compatible and Typescript-focused.
61 lines (60 loc) • 2.55 kB
JavaScript
import { closestWithin } from './lib/closestWithin';
import { isNil } from './lib/assertions';
var EventHandler = /** @class */ (function () {
function EventHandler(config) {
var _this = this;
this.config = config;
this._isAttached = false;
this._isDestroyed = false;
// If config has an object for listenerOptions with { once: true }, create a surrogate
// listenerOptions object with { once: false } for the actual native listener.
// We want the listener to detach after one callback execution rather than after the first
// event. The first event(s) might not match the given selector, resulting in the listener
// callback to never run:
this.actualListenerOptions = this.isOnceListener()
? Object.assign({}, config.listenerOptions, { once: false })
: config.listenerOptions;
this.handler = function (event) {
var delegator = closestWithin(event.target, config.selector, config.root);
if (isNil(delegator)) {
return;
}
config.listener.call(delegator, Object.assign(event, { delegator: delegator }));
// If this is a { once: true } listener we'll manually remove the listener after the first matching event:
if (_this.isOnceListener()) {
_this.remove();
}
};
config.root.addEventListener(config.eventType, this.handler, this.actualListenerOptions);
this._isAttached = true;
}
EventHandler.prototype.isAttached = function () {
return this._isAttached;
};
EventHandler.prototype.isDestroyed = function () {
return this._isDestroyed;
};
EventHandler.prototype.root = function () {
return this.config.root;
};
EventHandler.prototype.selector = function () {
return this.config.selector;
};
EventHandler.prototype.eventType = function () {
return this.config.eventType;
};
EventHandler.prototype.remove = function () {
if (this._isDestroyed) {
return;
}
this.config.root.removeEventListener(this.config.eventType, this.handler, this.actualListenerOptions);
this._isDestroyed = true;
this._isAttached = false;
};
EventHandler.prototype.isOnceListener = function () {
return typeof this.config.listenerOptions === 'object'
&& this.config.listenerOptions.once === true;
};
return EventHandler;
}());
export { EventHandler };