JSFiddle - React, Tailwind, and code Playground
by neonDog
HTML
<button class="btn">
Hello test
</button>
<div class="btn">
Hello test <b>test</b>
</div>
JavaScript
function defineCurrentTarget(event, getter) {
if (!currentTargetDesc) return;
Object.defineProperty(event, 'currentTarget', {
configurable: true,
enumerable: true,
get: getter || currentTargetDesc.get
});
}
const delegate = (...delegateArgs) => {
let args = delegateArgs;
if (args.length === 3) {
args = [[document.documentElement], ...args];
}
if (args[0].constructor.name === 'String') {
args[0] = [...document.querySelectorAll(args[0])];
} else if (!args[0].forEach) {
args[0] = [args[0]];
} else {
args[0] = [...args[0]];
}
if (args[2].constructor.name !== 'String') {
if (!args[2].forEach) {
args[2] = [args[2]];
} else {
args[2] = [...args[2]];
}
}
const [elements, eventListeners, selector, callback] = args;
const events = eventListeners.split(' ');
const callMethod = (e) => {
let delegateTarget;
if (selector.constructor.name === 'String') {
delegateTarget = e.target.closest(selector);
} else {
[delegateTarget] = selector.filter(node => (
node === e.target || node.contains(e.target)
));
}
if (delegateTarget) {
e.relatedElements = elements;
e.currentTarget = delegateTarget;
callback.call(delegateTarget, e, delegateTarget);
}
};
elements.forEach((element) => {
events.forEach((event) => {
element.addEventListener(event, callMethod, true);
});
});
return callMethod;
};
const ev = delegate('click', '.btn', (e, ele) => {
// Event object
const eventObj = e;
// Element that triggered event - '.btn'
const targetElement = e.currentTarget;
// Array of Elements that event is bound to - [document]
const boundElement = e.relatedElements;
console.error(eventObj);
console.error(targetElement);
console.error(boundElement);
});
console.log(ev);