; (function (root, factory) { // Browser globals root.MyEvent = factory(); }(typeof self !== 'undefined' ? self : this, function () { let registeredEvents = []; let supportedEvents = ['click', 'submit', 'change']; function isValidSelector(selector) { let matches = null; matches = selector.match(/^#([a-zA-Z0-9\-\_]+)$/); if (matches) { return { type: 'ID', value: matches[1] }; } matches = selector.match(/^\.([a-zA-Z0-9\-\_]+)$/); if (matches) { return { type: 'CLASS', value: matches[1] }; } matches = selector.match(/^([a-z][a-z0-9]{0,20})$/); if (matches) { return { type: 'TAG', value: matches[1] }; } return false; } function addEventListener(event, selector, callback) { if (!supportedEvents.includes(event)) { throw new Error('Event \'' + event + '\' is not suppored.'); } let sel = isValidSelector(selector); if (!sel) { throw new Error('Invalid registered event selector \'' + selector + '\'.'); } registeredEvents.push({ event: event, selector: sel, callback: callback }); } supportedEvents.forEach(function (event) { document.addEventListener(event, function (e) { let element = e.target; let listeners = registeredEvents.filter(function (item) { return item.event === event; }); listeners.forEach(function (listener) { let type = listener.selector.type; let value = listener.selector.value; let myCurrentTarget = null; if (type === 'ID') { myCurrentTarget = element.closest('#' + value); } else if (type === 'CLASS') { myCurrentTarget = element.closest('.' + value); } else if (type === 'TAG') { myCurrentTarget = element.closest(value); } if (myCurrentTarget) { e.myCurrentTarget = myCurrentTarget; listener.callback(e); } }); // console.log(executableListeners.length + ' listener' + // (executableListeners.length == 1 ? '' : 's') + ' executed'); }); }); return { addEventListener: addEventListener }; }));