Почему некоторые обработчики событий запускаются dispatchEvent, а другие нет?

#javascript #events #browser #dom-events

#javascript #Мероприятия #браузер #dom-события

Вопрос:

Существует два основных API для JS на основе событий: прослушиватели событий и обработчики событий. Прослушиватели событий регистрируются с addEventListener помощью, а обработчики событий регистрируются с помощью API, подобного target.onfoobar = (ev) => { ... } . Затем события могут быть отправлены с dispatchEvent помощью . Но мне не ясно, как / когда / dispatchEvent вызывает ли обработчики событий.

Моя первоначальная ментальная модель заключалась в том, что обработчики событий вызываются в конце dispatchEvent . То есть, dispatchEvent будет выглядеть примерно так:

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

Иногда dispatchEvent вызывает обработчик событий:

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

Но в других случаях dispatchEvent НЕ вызывает обработчик событий:

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

Я не знаю, как объяснить это несоответствие.
В чем разница между этими двумя случаями?
Это click «стандартный» тип события,
но xyz это не так?
Если да, то что представляет собой «стандартный» тип события
и как dispatchEvent узнать разницу?

Комментарии:

1. on префикс для свойства не имеет особого значения — onclick это определенный метод для некоторых вещей, таких как элементы HTML … onxyz это просто имя свойства, т. Е. Ваш «ментальный модальный» имеет недостатки… в любом случае … если вы скажете onclick=fna тогда onclick=fnb fnb вызывается только … тогда как это будет addEventListener соответствовать вашей модели? поскольку у вас может быть столько eventListener s, сколько вам нравится!

Ответ №1:

Это потому onclick , что является частью HTMLElement интерфейса (через его включение GlobalEventHandlers, который, в свою очередь, ссылается на спецификацию событий пользовательского интерфейса), а onxyz не является. onxyz насколько известно браузеру, это просто ваше собственное свойство expando, не связанное с событиями.

Пользовательские события поддерживаются, просто у них нет собственного специального свойства, поэтому вам нужно использовать соответствующий метод регистрации событий ( addEventListener в современных системах, attachEvent в устаревших версиях Internet Explorer):

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