Sep 15

Днес ми се наложи да направя нещо такова:

function action(){ /* ... code ... */ };
$(element).observe('click', action);
action.call($(element));

да декларираш функция която да се извика само един път, и при това, че я има като event-handler, е нещо, което винаги съм мразил да правя.
Но за щастие се сетих за “The “other” problem”, и по точно за тази част от поста:

Даже John-David Dalton е направил и Prototype версия : http://pastie.org/255119, от която най-много ми хареса допълнението на Element.fire, която я очаквам в новата версия на Prototype :)

Така че само с това малко парче код:

Element.addMethods({
	fire: Event.fire.wrap(function(proceed, element, eventName, memo) {
		element = $(element);
		var w, event, eventID;
		// ако eventName е например "click mouseover custom:event",
		// ще се симулират деиствията: click mouseover custom:event
		$w(eventName)._each(function(name) {
			// просто ако диствието е custom:event
			// си се вика нормалния Еvent.fire
			if (name.include(':'))
				return proceed(element, name, memo);

			// тук е първо се взема eventID-то на елемента
			// после ако е имало такова eventID се вземат event.cache всичките
			// event handle-и за този event
			eventID = (element._prototypeEventID || [null])[0];
			if (!eventID || !(w = Event.cache[eventID][name])) return false;

			// просто се прави "лъжлив" event обект
			event = Event.extend({ });
			event.eventName = name;
			event.memo = memo || { };

			// извикват се event handle-и
			w._each(function(wrapper) { wrapper(event) });
		});
		return element;
	})
});

Горния проблем се решава просто така:

$(element).observe('click', function action(){ /* ... code ... */ }).fire('click');

Което освен, че е по-кратко, е и по-красиво. / За по-разбираемо, не знам, защото аз си го разбирам де :) /

Какво мислите по въпроса