Статьи

Как создать пользовательские события в JavaScript

Обработка событий JavaScript является основой всех клиентских приложений. Когда на целевом элементе происходит событие, например, нажатие кнопки, перемещение мыши, отправка формы и т. Д., Выполняется функция обработчика. Объект события передается в обработчик, который предоставляет различные свойства и ряд методов для предотвращения действий по умолчанию.

Одним из недостатков является то, что события неразрывно связаны с элементами DOM. Рассмотрим простую форму, которая принимает сообщения от пользователя:


<form id="msgbox" action="#" method="get">
<label for="msg">your message</label>
<input id="msg" value="" />
<button>SEND</button>
</form>

Мы можем написать обработчик для отображения сообщений на экране при отправке этой формы, например

 
document.getElementById("msgbox").addEventListener("submit", function(e) {
	e.preventDefault();
	var msg = e.currentTarget.getElementById("msg").value.trim();
	if (msg) {
		alert(msg);
	}
}, false);

Что если мы также хотим отправить сообщение в виде твита, сохранить его на сервере или выполнить другие действия? У нас есть два варианта с существующими методами делегирования событий:

  1. Добавьте дополнительный код в наш существующий обработчик.
    Это негибко, поскольку нам нужно обновлять и тестировать нашу функцию обработчика каждый раз, когда мы добавляем, изменяем или удаляем функциональность. Для опубликованного сообщения может быть множество применений, и мы пытаемся применить их все в одном блоке кода.
  2. Создайте дополнительные обработчики событий для каждого использования.
    Это приведет к более элегантному коду, но приведет к проблемам с обслуживанием. Во-первых, каждая функция должна выполнять аналогичные действия для извлечения и проверки сообщения. А что если нам нужно изменить нашу форму? Простое переименование идентификатора потребовало бы от нас изменения кода обработки событий для каждого подписчика.

Разве не было бы замечательно, если бы мы могли просто вызывать пользовательское событие «newMessage» всякий раз, когда размещается верное сообщение? Было бы даже лучше, если бы мы могли просто отслеживать тег документа или bodyform Это именно то, что позволяют нам специальные события.

Поднять пользовательское событие просто; мы передаем имя, детали и параметры новому объекту CustomEvent:

 
var event = new CustomEvent(
	"newMessage", 
	{
		detail: {
			message: "Hello World!",
			time: new Date(),
		},
		bubbles: true,
		cancelable: true
	}
);

В этом примере «newMessage» — это пользовательский тип события. Второй параметр — это объект с тремя свойствами:

  • detail : дочерний объект, предоставляющий пользовательскую информацию о событии. В этом примере мы добавили сообщение и время.
  • пузыри : если истина, события будут пузыриться предкам элемента, который вызвал событие.
  • cancellable : если true, события могут быть отменены с помощью метода stopPropagation () объекта события.

Теперь нам нужно отправить это событие на определенный элемент, например

 
document.getElementById("msgbox").dispatchEvent(event);

Любое количество обработчиков может подписаться на это событие, используя такой код:

 
document.addEventListener("newMessage", newMessageHandler, false);

Демонстрационная страница

Этот пример демонстрирует технику:

Просмотреть страницу демонстрации пользовательских событий

Стандартный обработчик событий ищет отправку в форме HTML выше. Функция получает текущее сообщение и, если оно действительно, отправляет новое событие «newMessage».

 
var msgbox = document.getElementById("msgbox");
msgbox.addEventListener("submit", SendMessage, false);

// new message: raise newMessage event
function SendMessage(e) {

	e.preventDefault();
	var msg = document.getElementById("msg").value.trim();

	if (msg && window.CustomEvent) {
		var event = new CustomEvent("newMessage", {
			detail: {
				message: msg,
				time: new Date(),
			},
			bubbles: true,
			cancelable: true
		});
	
		e.currentTarget.dispatchEvent(event);
	}

}

Теперь обработчики могут подписаться на события «newMessage». События генерируются только при наличии действительного сообщения и, поскольку для пузырьков установлено значение true, событие можно применить к форме или любому из ее предков, например к корневому документу, например

 
// listen for newMessage event
document.addEventListener("newMessage", newMessageHandler, false);

// newMessage event handler
function newMessageHandler(e) {
	LogEvent(
		"Event subscriber on "+e.currentTarget.nodeName+", "
		+e.detail.time.toLocaleString()+": "+e.detail.message
	);
}

Само сообщение может быть извлечено из свойства detail.message объекта события.

Совместимость браузера

На момент написания, объект CustomEvent поддерживается Chrome, Firefox и Opera. Он доступен в ночных выпусках Safari, поэтому он скоро появится в этом браузере.

IE9 и ниже не поддерживают объект. К счастью, несколько библиотек JavaScript поддерживают делегирование пользовательских событий, поэтому в скором времени продолжайте следить за SitePoint для кросс-браузерного решения.

И если вам понравилось читать этот пост, вы полюбите Learnable ; место, чтобы узнать новые навыки и приемы у мастеров. Участники получают мгновенный доступ ко всем электронным книгам SitePoint и интерактивным онлайн-курсам, таким как Jump Start JavaScript .

Комментарии к этой статье закрыты. У вас есть вопрос о JavaScript? Почему бы не спросить об этом на наших форумах ?