Nov 15

Това е втория пост за ControlDepo 3 WidgetsBehaviors (по план имам още един :) ).

Преди време ми се наложи да “освежавам” един стар проект използващ една от първите версии на CD3.Behaviors. Тази стара версия имаше само нормален селектор | event-селектори. Там забелязах че много често ползвам pattern (това ако някой на български ми го каже как е, ще съм много благодарен) а именно:

CD3.Behavoirs({
	'#container': function(contaner){
		contener.select('a').invoke('click', doSomeAction);
		contaner.select('a').invoke('mouseover', doSomeOtherAction);
		// .. и така си избирам всичките под елементи на #container и да им добавям event handler
	}
});

Това е примерен код за простичка javascript галерия, която има два бутона предишна / следваща картинка както и списък с thumbnail-и от който пак може да се покаже голямата снимка.  selectImage просто от a таг взема href атрибута и го показва като снимка с ефект и т.н, но то не е важното в случая.

CD3.Behaviors({
	// code
	'#gallery': function(){
		// при натискане на стрелката за предишна снимка да ...
		this.down('a.prev').observe('click', function(){
			var thumbs	 = $('thumbs'),
				selected = thumbs.down('a.selected');

			// покажи или предишнина или послената снимка
			selectImage(((selected && selected.up('li').previous('li')) || thumbs.select('li').last()).down('a'));
		});

		// при натискане на стрелката за следваща снимка да ...
		this.down('a.next').observe('click', function(){
			var thumbs	 = $('thumbs'),
				selected = thumbs.down('a.selected');

			// покажи следващата или първата снимка
			selectImage(((selected && selected.up('li').next('li')) || thumbs.select('li').first()).down('a'));
		});

		// тук правя много прост event delegation
		// избирам натиснатия a таг и викам selectImage с него
		$('thumbs').observe('click', function(e){
			e.stop();
			var a = e.findElement('a');
			if (a) selectImage(a);
		});
	}
	// code
});

Естествено някой от случаите могат да бъдат избегнати с event-delegation | инстанциране на класове, но  ми дойде друга, по-добра (според мен) идея. Добавих нов метод към CD3.Behavoirs – when. CD3.Behavios.when приема 2 параметъра 1вия е selector, а другия е hash object с behavoirs. Идеята се намерят елементи отговарящи на подадения селектор, се добавят и съответните behavoirs. Единственото по особеност тук е че selector-ите на behavoir-ите не се търсят в контекста на document а в контекста на елемента на който отговаря selectora подаден като първи аргумент.

И така със CD3.Behavios.when примера със новинарската джаджа изглежда така:

// ако съществува елементи #galley
// добави слените behaviors от контекста на #gallery
CD3.Behaviors.when('#gallery', {
	// при натискане на стрелката за предишна снимка да ...
	'a.prev:click': function(){
		var thumbs	 = $('thumbs'),
			selected = thumbs.down('a.selected');

		// покажи или предишнина или послената снимка
		selectImage(((selected && selected.up('li').previous('li')) || thumbs.select('li').last()).down('a'));
	},
	// при натискане на стрелката за следваща снимка да ...
	'a.next:click': function(){
		var thumbs	 = $('thumbs'),
			selected = thumbs.down('a.selected');

		// покажи следващата или първата снимка
		selectImage(((selected && selected.up('li').next('li')) || thumbs.select('li').first()).down('a'));
	},
	// избирам натиснатия a таг и викам selectImage с него
	'thumbs:click': {
		a: function(е){
			е.stop();
			selectImage(this);
		}
	}
});

Както се вижда кода е почти същия но сега изглежда доста по-добре и по-четим. В последните ми няколко по-натоварени с javascript проекти си структурирам джаджите в отделни извиквания на when и нещата изглеждат доста добре.

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