eventHandler = function (e){	if (this.obj)	{		if (this.obj.blockEvent)		{			e = e ? e : window.event;			if (e.stopPropagation) e.stopPropagation();			else e.cancelBubble = true;			if (e.preventDefault) e.preventDefault();			else e.returnValue = false;		}		if (e)		{			this.obj.event = e;			this.handler();		}	}}timeoutHandler = function (elem){	return function ()	{		elem.timeoutHandler();	}}/************************************************************Добавление новых функций для элемента$ - поиск элемента по idgetByClassName - поиск по названию классаgetByClassNameAndTagName - поиск по названию класса и названию тэгаhideElem - скрытие элемента немедленныйshowElem - показ элемента немедленныйtoggleElem - скрытие показ в зависимости от текущего состояния************************************************************/// TODO вынести fade в отдельную структуру, хайд и шоу в отдельную, сделать мейкер EEExtendElem = function (hideClass, enableFade, minFadeOpacity, maxFadeOpacity, fadeShots){	this.hiddenClassName = hideClass.split('|')[0];	this.visibleClassName = hideClass.split('|')[1];	this.enableFade = enableFade;	this.minFadeOpacity = minFadeOpacity ? minFadeOpacity : 0;	this.maxFadeOpacity = maxFadeOpacity ? maxFadeOpacity : 1;	this.fadeShots = fadeShots ? fadeShots : 15;	this.allElems = document.getElementsByTagName('*');	this.$ = function (id)	{		return document.getElementById(id) || false;	}	this.setOpacityFunction = function ()	{		if (!window.opera && !navigator.product)		{			return function (value)			{				value *= 100;				this.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + value + ')';				return true;			}		}		else		{			return function (value)			{				this.style.opacity = value;				return true;			}		}	}	this.getByClassName = function (className, parent)	{		var parent = parent ? parent : this.allElems;		var result = new Array();		for (var i = 0; i < parent.length; i++)		{			if (parent[i].className.search(className) > -1)			{				result.push(parent[i]);			}		}		return result;	}	this.getByClassNameAndTagName = function (className, tagName, parent)	{		var parent = parent ? parent : this.allElems;		var result = new Array();		var parent = this.getByClassName(className, parent);		for (var i = 0; i < parent.length; i++)		{			if (parent[i].tagName == tagName)			{				result.push(parent[i]);			}		}		return result;	}	this.checkStatus = function ()	{		return this.className.search(this.ee.visibleClassName) > -1;	}	this.hideElem = function ()	{		this.className = this.className.replace(this.ee.visibleClassName, this.ee.hiddenClassName);		return true;	}	this.showElem = function ()	{		this.className = this.className.replace(this.ee.hiddenClassName, this.ee.visibleClassName);		if (this.focusElem)		{			this.focusElem.focus();		}		return true;	}	this.toggleElem = function ()	{		this.checkStatus() ? this.hide() : this.show();		return true;	}	this.fadeToggleElem = function ()	{		this.checkStatus() ? this.fadeOut() : this.fadeIn();		return true;	}	this.fadeIn = function ()	{		clearTimeout(this.fadeTimeout);		this.timeoutHandler = this.fadeIn;		this.show();		if (!this.fadeOpacity)		{			this.fadeOpacity = this.ee.minFadeOpacity;		}		if (this.fadeOpacity >= this.ee.maxFadeOpacity)		{			this.fadeOpacity = this.ee.maxFadeOpacity			this.setOpacity(this.fadeOpacity);			// done!		}		else		{			this.fadeOpacity += (this.ee.maxFadeOpacity - this.ee.minFadeOpacity) / this.ee.fadeShots;			this.setOpacity(this.fadeOpacity);			this.fadeTimeout = setTimeout(timeoutHandler(this), 40);		}	}	this.fadeOut = function ()	{		clearTimeout(this.fadeTimeout);		this.timeoutHandler = this.fadeOut;		if (!this.fadeOpacity)		{			this.fadeOpacity = this.ee.maxFadeOpacity;		}		if (this.fadeOpacity <= this.ee.minFadeOpacity)		{			this.fadeOpacity = this.ee.minFadeOpacity			this.setOpacity(this.fadeOpacity);			this.hide();			// done!		}		else		{			this.fadeOpacity -= (this.ee.maxFadeOpacity - this.ee.minFadeOpacity) / this.ee.fadeShots;			this.setOpacity(this.fadeOpacity);			this.fadeTimeout = setTimeout(timeoutHandler(this), 40);		}	}	this.add = function (elem)	{		elem.ee = this;		if (this.enableFade)		{			elem.setOpacity = this.setOpacityFunction();			elem.fadeIn = this.fadeIn;			elem.fadeOut = this.fadeOut;			elem.fadeToggle = this.fadeToggleElem;		}		elem.hide = this.hideElem;		elem.show = this.showElem;		elem.toggle = this.toggleElem;		elem.checkStatus = this.checkStatus;	}}/************************************************************Выключатель с двумя и более активными элементами.Включатель и выключатель раздельные.Выключателей и включателей может быть какой угодно количество, активный элемент только один.Парамметры:blockClassName - имя класса открываемого блока (уникальное или берется первый найденный)openClassName - имя класса всех открывашекcloseClassName - имя класса для все закрывашекhideClass - названия классов для скрытия и показа блока в формате: скрыт|показанopenAsClose - открывашка при повторном клике закроетcloseAsOpen - закрывашка при повторном клике откроет************************************************************/BlockToggler = function (blockClassName, openClassName, closeClassName, hideClass, openAsClose, closeAsOpen, blockEvent){	this.blockClassName = blockClassName;	this.blockElem = new Array();	this.openClassName = openClassName;	this.openElems = new Array();	this.closeClassName = closeClassName;	this.closeElems = new Array();	this.event = false;	this.openAsClose = openAsClose;	this.closeAsOpen = closeAsOpen;	this.ee = new ExtendElem(hideClass, true);	this.blockEvent = blockEvent;	this.openBlock = function ()	{		this.obj.blockElem.show();	}	this.toggleBlock = function ()	{		this.obj.blockElem.fadeToggle();	}	this.closeBlock = function ()	{		this.obj.blockElem.hide();	}	this.prepare = function ()	{		if (this.blockClassName)		{			this.blockElem = this.ee.getByClassName(this.blockClassName, false);		}		if (this.openClassName)		{			this.openElems = this.ee.getByClassName(this.openClassName, false);		}		if (this.closeClassName)		{			this.closeElems = this.ee.getByClassName(this.closeClassName, false);		}		if (this.blockElem.length)		{			/* берем первый элемент */			this.blockElem = this.blockElem[0];			this.blockElem.obj = this;			this.ee.add(this.blockElem);			for (var i = 0; i < this.openElems.length; i++)			{				this.openElems[i].obj = this;				if (this.openAsClose)				{					this.openElems[i].handler = this.toggleBlock;				}				else				{					this.openElems[i].handler = this.openBlock;				}				this.openElems[i].onclick = eventHandler;			}			for (var i = 0; i < this.closeElems.length; i++)			{				this.closeElems[i].obj = this;				if (this.closeAsOpen)				{					this.closeElems[i].handler = this.toggleBlock;				}				else				{					this.closeElems[i].handler = this.closeBlock;				}				this.closeElems[i].onclick = eventHandler;			}		}	}	this.prepare();}/***************************************************************example:classNameRule = 'PrefixRoleId'or:classNameRule = 'RolePrefixId'prefix - та часть которая всех объединяетrole - роль элемента, например toggler или block (переключатель или переключаемый блок)id - та часть которая объединяет переключатель и блок***************************************************************/radioToggler = function (prefix, activeElemRole, passiveElemRole, classNameRule, hideClass, openAsClose, blockEvent, fade){	this.ee = new ExtendElem(hideClass, fade);	this.fade = fade;	this.prefix = prefix;	this.activeElemRole = activeElemRole;	this.passiveElemRole = passiveElemRole;	this.classNameRule = classNameRule;	this.openAsClose = openAsClose;	this.activeElems = new Array();	this.passiveElems = new Array();	this.blockEvent = blockEvent;	this.makeClassName = function (active, id)	{		var role = active ? this.activeElemRole : this.passiveElemRole;		return this.classNameRule.replace('Prefix', this.prefix).replace('Role', role).replace('Id', id);	}	this.getElemId = function (elem)	{		var classes = elem.className.split(' ');		for (var i = 0; i < classes.length; i++)		{			if (classes[i].search(this.prefix) > -1)			{				var className = classes[i];				if (classes[i].search(this.activeElemRole) > -1)				{					var role = this.activeElemRole;					break;				}				else (classes[i].search(this.passiveElemRole) > -1)				{					var role = this.passiveElemRole;					break;				}			}		}		return className.replace(this.prefix, '').replace(role, '');	}	// FIXME при быстром переключении туда-обратно срабатывает fadeOut вместо fadeIn и все элементы скрываются	this.toggleElem = function (elem, className, fade)	{		// проверяем на сходство с текущим переключателем для активизации		if (elem.className.search(className) > -1)		{			// Смотрим активен ли сейчас текущий элемент			if (elem.checkStatus())			{				// если элемент и так показан, то при наличие openAsClose его нужно скрыть				if (this.openAsClose)				{					elem.hide();				}			}			// не активен - показываем			else			{				fade ? elem.fadeIn() : elem.show();			}		}		// не совпал, прячем если активен		else		{			if (elem.checkStatus())			{				fade ? elem.fadeOut() : elem.hide();			}		}	}	this.toggleRadio = function ()	{		var id = this.obj.getElemId(this);		var activeClassName = this.obj.makeClassName(true, id);		var passiveClassName = this.obj.makeClassName(false, id);		for (var i = 0; i < this.obj.activeElems.length; i++)		{			this.obj.toggleElem(this.obj.activeElems[i], activeClassName);		}		for (var i = 0; i < this.obj.passiveElems.length; i++)		{			this.obj.toggleElem(this.obj.passiveElems[i], passiveClassName, this.obj.fade);		}	}	this.prepare = function ()	{		var activeClassName = this.makeClassName(true, '');		var passiveClassName = this.makeClassName(false, '');		this.activeElems = this.ee.getByClassName(activeClassName);		this.passiveElems = this.ee.getByClassName(passiveClassName);		for (var i = 0; i < this.activeElems.length; i++)		{			this.activeElems[i].obj = this;			this.ee.add(this.activeElems[i]);			this.activeElems[i].handler = this.toggleRadio;			this.activeElems[i].onclick = eventHandler;		}		for (var i = 0; i < this.passiveElems.length; i++)		{			this.passiveElems[i].obj = this;			this.ee.add(this.passiveElems[i]);		}	}	this.prepare();}
