jameshfisher
jameshfisher

Reputation: 36639

Why are some event handlers triggered by dispatchEvent, but others are not?

There are two basic APIs for event-based JS: event listeners and event handlers. Event listeners are registered with addEventListener, and event handlers are registered with an API like target.onfoobar = (ev) => { ... }. Events can then be dispatched with dispatchEvent. But it's not clear to me how/when/whether dispatchEvent calls event handlers.

My initial mental model was that event handlers are called at the end of dispatchEvent. That is, dispatchEvent would look something like this:

EventTarget.prototype.dispatchEvent = function(event) {
  // First dispatch to this.listeners, then:
  const handler = this['on'+event.type];
  if (handler) handler(event);
};

Sometimes, dispatchEvent does call the event handler:

window.onclick = () => console.log("this IS called!!");
window.dispatchEvent(new Event("click"));

But other times, dispatchEvent does NOT call the event handler:

window.onxyz = () => console.log("this is NOT called!!");
window.dispatchEvent(new Event("xyz"));

I don't know how to explain this disparity. What is the difference between these two cases? Is it that click is a "standard" event type, but xyz is not? If so, what constitutes a "standard" event type, and how does dispatchEvent know the difference?

Upvotes: 1

Views: 1482

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1075895

It's because onclick is part of the HTMLElement interface (via its include of GlobalEventHandlers, which in turn refers to the UI Events specification), and onxyz is not. onxyz is just your own expando property with no connection to events as far as the browser knows.

Custom events are supported, they just don't have their own special property, so you have to use the appropriate event registration method (addEventListener in modern systems, attachEvent in obsolete versions of Internet Explorer):

window.addEventListener("xyz", () => console.log("this IS called!!"));
window.dispatchEvent(new Event("xyz"));

Upvotes: 2

Related Questions