The recipe of event delegating from http://youmightnotneedjquery.com/:
document.addEventListener(eventName, function(e) {
// loop parent nodes from the target to the delegation node
for (var target = e.target; target && target != this; target = target.parentNode) {
if (target.matches(elementSelector)) {
handler.call(target, e);
break;
}
}
}, false);
I am trying rewrite it to TypeScript type-safely (for click event for now):
export default function delegateClickEventHandling(
{
clickTargetSelector,
container = document
}: {
clickTargetSelector: string;
container: HTMLElement | Document;
},
handler: (event: MouseEvent) => void
): void {
container.addEventListener("click", (event: Event): void => {
if (!(event instanceof MouseEvent)) {
return;
}
for (
let targetParentNode: Element | null = event.target as Element;
isNotNull(targetParentNode) && targetParentNode !== event.currentTarget;
targetParentNode = targetParentNode.parentNode
) {
if (targetParentNode.matches(clickTargetSelector)) {
handler(event);
}
}
}, false);
}
TypeScript compiler tells me:
TS2322: Type '(Node & ParentNode) | null' is not assignable to type 'Element | null'.
Type 'Node & ParentNode' is not assignable to type 'Element | null'.
Type 'Node & ParentNode' is missing the following properties from type 'Element':
assignedSlot, attributes, classList, className, and 64 more.
The .matches() is the method of the Element - I can't to call it from Node & ParentNode).
What have I do?
If targetParentNode = targetParentNode.parentNode as Element is completely all right please explain why.
P. S. Please note that any, object and type annotation omitting are not allowed.
You just need to cast targetParentNode.parentNode to Element.
So for loop might be look like this:
for (
let targetParentNode: Element = event.target as Element;
targetParentNode !== event.currentTarget;
targetParentNode = targetParentNode.parentNode as Element
) {
if (targetParentNode.matches(clickTargetSelector)) {
handler(event);
}
}
PlaygrounLink
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With