/** * @projectDescription	Barrierearmes, gebrauchstaugliches Dropdownmenu * * @author 	Alexander Farkas <a.farkas@pfirsichmelba.de> // http://pfirsichmelba.de *  * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. *  * Bei guten Verbesserungen/öffentlichem Einsatz wäre ich für eine kurze Mail mit Link dankbar. *  * @version 0.5 * @param {String} $selektor CSS-selector of the wrapping element, id-selector = beeter performance * @param {options} [_settings] list of sveral options/settings *  * @option {Number|Array} [NavTimeout] delay to hide menu, if ypu use an array of two numbers, first is the delay for firstsubmenu, second for all other submenus, default is 250 * @option {String} [ListType] listtype i.e. ol (default = ul) * @option {Number} [LimitLinks] 1 = (default) .active and .activepath submenus are available for keyboard users, Opera browser overrirdes this (because of spatial navigation),0 = all submenus are available for keyboard users. if you use this you should remove display:none for submenus -> better consistency for screenreader (the submenus stay hidden / are out of viewport), 2 = .active and .activepath submenus are available for keyboard users (Opera browser doesn´t override this) *  * You need CleannCSSAnimation for effects (CleanCSSAnimation removes the inline style "display: none" after animations -> good for screenreaders and keyboard-user): * CleannCSSAnimation Plugin: http://pfirsichmelba.de/artikel-scripts/lib/jq.cleanCSSanim.js * @option {Number} [Effect] needs CleannCSSAnimation plugin: 0 = no Effect (default), 1 = show and hide effect, 2 = show-effect, 3 = hide-effect * @option {String} [ShowEffect] Name of show effect, default=show * @option {String} [HideEffect] Name of hide effect, default=hide * @option {String|Number} [EffectSpeed] Speed of show and hide effect, default=300 *  * You need Dimensions Plugin for jQuery: * @option {String} [Fit2ViewportClass] class-value for submenu, wich does not fit the viewport-width, default=false (= don´t check viewport width) * @option {Number} [FitIfViewportSmaller] only check, wether submenus fit viewport-width, if viewport is smaller than given option, default=1111 (if you want to check always set it to 9999, yopu have to set "Fit2ViewportClass")*///  You sould compress/obfuscate this javascript-file....function DickerFisch($selektor,_settings) {	//config start	//classnames: Styles	// _DF_hoverclass = Hover-Class für mouseover LI und LI-Eltern von fokusierten a-Elementen	// _DF_parent_class = Wenn zur Kategorie noch Unterkategorien gehören wird das LI-Element ausgezeichnet	// $ofocusstyle = Opera verliert optische Markierung bei Tastaturnutzung fügt ans fokusierte a die nachfolgende id an.	var _DF_hoverclass = 'over', _DF_parent_class = 'parent',$ofocusstyle = 'ofocus';	//Array 0 = ancestors of active li-category | 1 = active li category	var _DF_ActiveCatnAncestorsofIT = new Array(".activepath", ".active");	var _jsreadyclass = 'navfxenabled';	//_DF_hideclass = Soll versteckt werden; _waitingnavclass = Wartet darauf ausgeklappt zu werden	var  _DF_hideclass = 'DF_hidelis', _waitingnavclass = 'DF_waitlis';	// effect css-class: visible class value and hidden class value see/same in CleanCSSAnimation/unMakeInlineCSS, will be removed after animation	var $nodisClass = "displaynone",$disClass = "displayblock";	//config end	var _DF_obj = this;	//optional parameter	var _settings = _settings || this;	var _defaultNav = '#navigation ul.current';	this.NavTimeout = _settings.NavTimeout || 250;	this.ListType = _settings.ListType || 'ul';	this.Effect = (_settings.Effect) ? _settings.Effect : 0;	this.ShowEffect = _settings.ShowEffect || 'show';	this.HideEffect = _settings.HideEffect || 'hide';	this.EffectSpeed = _settings.EffectSpeed || 300;	this.FitIfViewportSmaller = _settings.FitIfViewportSmaller || 1111;	this.Fit2ViewportClass = _settings.Fit2ViewportClass || false;	this.LimitLinks = (typeof _settings.LimitLinks == "number") ? _settings.LimitLinks : 1;	_DF_obj.LimitLinks = ($.browser.opera && _DF_obj.LimitLinks == "1") ? 0 : _DF_obj.LimitLinks;	this._DF_NavTimeID;	//methods	this._fastpullout = function(_eventobj){		var $fastpullreturn = false;		if(typeof $($selektor+' li.'+_DF_hoverclass).get(0) == "undefined")			$fastpullreturn = true;		else {			$fastpullreturn = true;			$(_eventobj).siblings("li").each(function(i){				if($(this).is('.'+_DF_hoverclass)){					$fastpullreturn = false;					return false; //=break				}			});		}		return $fastpullreturn;	};	this.$oldtimer = 0;	this.$fastpullin = function(_eventobj){		var $aktimer = (typeof _DF_obj.NavTimeout != "number") ? _DF_obj.NavTimeout[1] : _DF_obj.NavTimeout;		if(typeof _DF_obj.NavTimeout != "number" && $(_eventobj).parents('li').length == "0" && !$(_eventobj).children(_DF_obj.ListType).children('li').is('.'+_DF_hoverclass))			$aktimer = _DF_obj.NavTimeout[0];		if($(_eventobj).is('.'+_DF_hoverclass) || _DF_obj.$oldtimer != $aktimer){			window.clearTimeout(_DF_obj._DF_NavTimeID);			_DF_obj._DF_NavTimeID = window.setTimeout(_DF_obj._hide,$aktimer);		}		_DF_obj.$oldtimer = $aktimer;	};	this.$navstatus = function(_eventobj,$action){		if($action == "show"){			$(_eventobj).addClass(_waitingnavclass).removeClass(_DF_hideclass);			if(_DF_obj._fastpullout(_eventobj))				_DF_obj.$show();		}else if($action == "hide")			$(_eventobj).removeClass(_waitingnavclass).addClass(_DF_hideclass);		_DF_obj.$fastpullin(_eventobj,'pullin');	};		this.$show = function(){		_showobj = $selektor+' li.'+_waitingnavclass;		if(_DF_obj.Effect == 1 || _DF_obj.Effect == 2)			$(_showobj+':not(.'+_DF_hoverclass+')>'+_DF_obj.ListType).addClass($nodisClass).CleanCSSAnimation(_DF_obj.ShowEffect,_DF_obj.EffectSpeed,function(){   				$(this).removeClass($disClass); 			});		$(_showobj).removeClass(_waitingnavclass).addClass(_DF_hoverclass).addClass(_DF_ActiveCatnAncestorsofIT[0]);	};	this._hide = function(){		$hideobj = $selektor+' li.'+_DF_hideclass;		if(_DF_obj.Effect == 1 || _DF_obj.Effect == 3)			$($hideobj).removeClass(_DF_hideclass).children(_DF_obj.ListType).CleanCSSAnimation(_DF_obj.HideEffect,_DF_obj.EffectSpeed,function(){   				$(this).removeClass($nodisClass).parent('li').removeClass(_DF_hoverclass);				_DF_obj.$show(); 			});		else{			$($hideobj).removeClass(_DF_hoverclass+' '+_DF_hideclass);			_DF_obj.$show();		}	};	this.FitToScreen = function($liobj){		var $subpos = $($liobj).addClass(_DF_hoverclass).children(_DF_obj.ListType).css('visibility','hidden').offset({scroll:false})['left'] + $($liobj).children(_DF_obj.ListType).outerWidth();		if(_viewport < $subpos)			$($liobj).children(_DF_obj.ListType).addClass(_DF_obj.Fit2ViewportClass);	};	if(_DF_obj.Fit2ViewportClass){		var _viewport = $(document).innerWidth();		_DF_obj.Fit2ViewportClass = (_viewport < _DF_obj.FitIfViewportSmaller) ? _DF_obj.Fit2ViewportClass : false;	}	//Init	//Ready -> let´s go	$($selektor+">"+_DF_obj.ListType).addClass(_jsreadyclass).find("li:has("+_DF_obj.ListType+")").each(function(){		//Mouse Init		$(this).hover(function() { 				_DF_obj.$navstatus(this,'show');				$($selektor+" .activepath").removeClass('activepath');			}, function() { 				_DF_obj.$navstatus(this,'hide');				$(_defaultNav).addClass('activepath');			}		).addClass(_DF_parent_class).find('a').focus(function() {			$(this).addClass($ofocusstyle);			if(_DF_obj.LimitLinks < 1) {			    				$($selektor+" .activepath").removeClass('activepath');				$(this).parents('li').addClass(_DF_hoverclass);					}			else				$(this).parents('li').filter(_DF_ActiveCatnAncestorsofIT[0]+','+_DF_ActiveCatnAncestorsofIT[1]).addClass(_DF_hoverclass);		} ).blur(function() {							$(_defaultNav).addClass('activepath');			$(this).removeClass($ofocusstyle).parents("li").removeClass(_DF_hoverclass);		});			if(_DF_obj.Fit2ViewportClass)			_DF_obj.FitToScreen(this);	});	if(_DF_obj.Fit2ViewportClass)		$($selektor+" li["+_DF_obj.ListType+"]").removeClass(_DF_hoverclass).children(_DF_obj.ListType).css('visibility','');};
