Как создать свое событие в jQuery?

Доброго времени.
Пишу свой модуль на JS, jQuery. Понадобилось событие "двойной правый клик". В jquery такого родного события нет, реализовал прям в модуле на скорую руку:

// Event
var limit = 400;
var lastClick, x, y = null;
this.on("contextmenu", ".slide", function(e) {
	e.preventDefault();

	if (x == e.screenX && y == e.screenY && (e.timeStamp - lastClick) < limit) {
		$(this).trigger("dblrightclick");
		lastClick, x, y = null;
	} else {
		x = e.screenX;
		y = e.screenY;
		lastClick = e.timeStamp;
	}
});

this.on("dblrightclick", ".slide", function(e) {
	// Logic here...
});


Что ж, все прекрасно, осталось только вынести логику события из модуля (не место ему там, да и может где еще пригодиться). Вот тут я и просел. К моему удивлению поиск по фразам типа "jquery create custom events" приводит к простейшим helloworld-ам по работе с событиями и использованию всяких bind() и trigger(). Возможно, я что-то не понимаю (очень надеюсь).

Собственно, вопрос: как описать свое событие со своей fire-логикой?

Я себе это представляю примерно так:

jQuery.createEvent("dblrightclick", function(elem) {
	elem.limit = elem.limit || 400;
	// Other basic init...

	elem.on("contextmenu", ".slide", function(e) {
		// Some logic
		elem.trigger(this);
	}.bind(this));
});
  • Вопрос задан
  • 12627 просмотров
Решения вопроса 1
@cmx Автор вопроса
Очевидно и по существу, никакими обсерверами, биндами и триггерами здесь не пахнет.
Решение оказалось не самое тривиальное, но архитектурно корректное и звучит как "Специальные события jQuery".
В рамках моей задачи, рабочая реализация выглядит следующим образом:
$.event.special.dblrightclick = {
	setup : function(data, namespaces) {
		var e = $(this);
		e.bind("contextmenu", $.event.special.dblrightclick.handler);
		e.data("x", null);
		e.data("y", null);
		e.data("time", null);
		e.data("limit", data || 400);
	},

	teardown : function(namespaces) {
		$(this).unbind("contextmenu", $.event.special.dblrightclick.handler);
	},

	handler : function (event) {
		event.preventDefault();
		var e = $(this);

		if (e.data("x") == event.screenX && e.data("y") == event.screenY
			&& (event.timeStamp - e.data("time")) < e.data("limit")) {
			e.data("x", null);
			e.data("y", null);
			e.data("time", null);
			event.type = "dblrightclick";
			$.event.dispatch.apply(this, arguments);
		} else {
			e.data("x", event.screenX);
			e.data("y", event.screenY);
			e.data("time", event.timeStamp);
		}
	}
};


И, соответственно, ее использование:
$("#widget").on("dblrightclick", ".button", function() {
	alert("dblrightclick fired");
});


А также управление единственным параметром задержкой:
$("#widget").on("dblrightclick", ".button", 200, function() {
	alert("dblrightclick fired");
});


Очевидно, что данный код является расширением базового фреймворка и не имеет никакого отношения к бизнес-логике приложения. Как следствие - данный код можно подключать бесконфликтно к разным проектам.

UPD Полное решение: https://github.com/comm1x/jquery-event-dblrightclick
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Видимо не понимаете. Действительно, создать свое событие в jquery можно через методы trigger/bind - первый вызывает событие, а второй его перехватывает. Фактически, реализация паттерна observer (bind - подписчик; trigger - публикация)
Ответ написан
ghaiklor
@ghaiklor
NodeJS TechLead
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы