UNPKG

@sergonius/click-boss

Version:

Handle all clicks in a single listener

63 lines (61 loc) 1.96 kB
class ClickBoss { static removeEvent(elem) { if (ClickBoss.events.has(elem)) { ClickBoss.events.delete(elem); ClickBoss.eventCount -= 1; if (ClickBoss.eventCount === 0) { ClickBoss.removeListener(); } return true; } throw Error('This element does not have a handler'); } static addEvent({ elem, fn }) { if (!(elem && elem.nodeType === Node.ELEMENT_NODE)) { throw Error('"elem" is mandatory and must be an element node'); } if (!(fn && typeof fn === 'function')) { throw Error('"fn" is mandatory and must be a function'); } if (ClickBoss.events.has(elem)) { throw Error('This element already has a handler. Remove the old one to add a new one.'); } if (!ClickBoss.listenerAdded) { ClickBoss.addListener(); } ClickBoss.events.set(elem, fn); ClickBoss.eventCount += 1; return true; } static addListener() { document.documentElement.addEventListener('click', listenerFn); ClickBoss.listenerAdded = true; } static removeListener() { document.documentElement.removeEventListener('click', listenerFn); ClickBoss.listenerAdded = false; } } ClickBoss.NODE_LIMIT = 10; ClickBoss.events = new WeakMap(); ClickBoss.listenerAdded = false; ClickBoss.eventCount = 0; function getTargetElem(elem, nodeLimit = ClickBoss.NODE_LIMIT) { if (nodeLimit === 0) { return false; } if (ClickBoss.events.has(elem)) { return elem; } if (elem.parentNode) { return getTargetElem(elem.parentNode, nodeLimit - 1); } return false; } function listenerFn(event) { const targetElem = getTargetElem(event.target); if (targetElem) { ClickBoss.events.get(targetElem).bind(targetElem)(event); } } export default ClickBoss;