demo · v130

Synthetic PointerEvent targets

Compare trusted browser pointer input with JS-constructed PointerEvents that carry coalesced sub-events. Trusted events follow browser hit-testing; untrusted events in Chrome 130+ keep each sub-event's original target instead of retargeting everything to the parent.

trusted vs untrusted target rules

Click or move over the targets to collect browser-generated trusted events. Then dispatch the same shape as an untrusted PointerEvent so the retained sub-event targets are visible side-by-side.

target A click or move here
target B click or move here
stream isTrusted parent target coalesced targets interpretation

log

the code

// Trusted browser input: target comes from hit-testing.
target.addEventListener("pointerdown", (event) => {
  console.log(event.isTrusted, event.target.id);
});

// Untrusted constructor input: the author supplies sub-events.
const coalesced1 = new PointerEvent("pointermove", { bubbles: true, pointerId: 1 });
a.dispatchEvent(coalesced1); // establishes the original target as A

const coalesced2 = new PointerEvent("pointermove", { bubbles: true, pointerId: 1 });
b.dispatchEvent(coalesced2); // establishes the original target as B

const event = new PointerEvent("pointermove", {
  pointerId: 1,
  bubbles: true,
  coalescedEvents: [coalesced1, coalesced2],
});

a.dispatchEvent(event);

// Chrome 130+: event.getCoalescedEvents()[0].target === a
//              event.getCoalescedEvents()[1].target === b
// Older behavior: both sub-events were retargeted to the parent.

see also