11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Quelqu'un aurait-il la gentillesse de me commenté ce bout de code que je puisse le comprendre.

Merci d'avance

		showSuperfishUl : function(){
			var o = sf.op,
				sh = sf.c.shadowClass+'-off',
				$ul = this.addClass(o.hoverClass)
					.find('>ul:hidden').css('visibility','visible');
			sf.IE7fix.call($ul);
			o.onBeforeShow.call($ul);
			$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
			return this;
Difficile étant donné que ce code semble être une méthode d'objet donc il manque bon nombre de propriétés et méthodes associés.

Grossomodo à ce que l'ont peut décortiquer il s'agit d'une méthode "showSuperfishUl" qui est appelée pour afficher une liste masqué avec une animation.
Il semble également y avoir une gestion de bug IE7 vu le nom de la méthode "IE7fix.call()".
Le code complet, en fait, j'aimerai pouvoir changer la methode onMouseHover par onClick pour que le menu soit compatible avec les mobile

/*
 * Superfish v1.4.8 - jQuery menu widget
 * Copyright (c) 2008 Joel Birch
 *
 * Dual licensed under the MIT and GPL licenses:
 * 	 http://www.opensource.org/licenses/mit-license.php
 
 * 	 http://www.gnu.org/licenses/gpl.html
 
 *
 * CHANGELOG:  http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
 
 */

// initialise plugins
jQuery(function(){
	jQuery('ul.sf-menu').superfish();
});
 
;(function($){
	$.fn.superfish = function(op){

		var sf = $.fn.superfish,
			c = sf.c,
			$arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
			over = function(){
				var $$ = $(this), menu = getMenu($$);
				clearTimeout(menu.sfTimer);
				$$.showSuperfishUl().siblings().hideSuperfishUl();
			},
			out = function(){
				var $$ = $(this), menu = getMenu($$), o = sf.op;
				clearTimeout(menu.sfTimer);
				menu.sfTimer=setTimeout(function(){
					o.retainPath=($.inArray($$[0],o.$path)>-1);
					$$.hideSuperfishUl();
					if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
				},o.delay);	
			},
			getMenu = function($menu){
				var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
				sf.op = sf.o[menu.serial];
				return menu;
			},
			addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
			
		return this.each(function() {
			var s = this.serial = sf.o.length;
			var o = $.extend({},sf.defaults,op);
			o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
				$(this).addClass([o.hoverClass,c.bcClass].join(' '))
					.filter('li:has(ul)').removeClass(o.pathClass);
			});
			sf.o[s] = sf.op = o;
			
			$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
				if (o.autoArrows) addArrow( $('>a:first-child',this) );
			})
			.not('.'+c.bcClass)
				.hideSuperfishUl();
			
			var $a = $('a',this);
			$a.each(function(i){
				var $li = $a.eq(i).parents('li');
				$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
			});
			o.onInit.call(this);
			
		}).each(function() {
			var menuClasses = [c.menuClass];
			if (sf.op.dropShadows  && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
			$(this).addClass(menuClasses.join(' '));
		});
	};

	var sf = $.fn.superfish;
	sf.o = [];
	sf.op = {};
	sf.IE7fix = function(){
		var o = sf.op;
		if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
			this.toggleClass(sf.c.shadowClass+'-off');
		};
	sf.c = {
		bcClass     : 'sf-breadcrumb',
		menuClass   : 'sf-js-enabled',
		anchorClass : 'sf-with-ul',
		arrowClass  : '',
		shadowClass : 'sf-shadow'
	};
	sf.defaults = {
		hoverClass	: 'sfHover',
		pathClass	: 'overideThisToUse',
		pathLevels	: 1,
		delay		: 300,
		animation	: {height:'show'},
		speed		: 'normal',
		autoArrows	: false,
		dropShadows : false,
		disableHI	: false,		// true disables hoverIntent detection
		onInit		: function(){}, // callback functions
		onBeforeShow: function(){},
		onShow		: function(){},
		onHide		: function(){}
	};
	$.fn.extend({
		hideSuperfishUl : function(){
			var o = sf.op,
				not = (o.retainPath===true) ? o.$path : '';
			o.retainPath = false;
			var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
					.find('>ul').hide().css('visibility','hidden');
			o.onHide.call($ul);
			return this;
		},
		showSuperfishUl : function(){
			var o = sf.op,
				sh = sf.c.shadowClass+'-off',
				$ul = this.addClass(o.hoverClass)
					.find('>ul:hidden').css('visibility','visible');
			sf.IE7fix.call($ul);
			o.onBeforeShow.call($ul);
			$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
			return this;
		}
	});

})(jQuery);
De ce que j'arrive à décortiquer, la gestion du mouseover se fait à cette ligne :

$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
    code executé 
}


Après une petite recherche on découvre que "hoverIntent" correspond à un plugin jQuery de gestion d'évenement souris (http://cherne.net/brian/resources/jquery.hoverIntent.html).

En regardant du côté de la documentation de Superfish on voit que le paramètre d'option "disableHI" permet d'activer ou désactiver l'utilisation du plugin hoverIntent.

La ligne de code plus haut permet donc de déterminer si l'on gère l'évènement mouseover avec le plugin hoverIntent ou la fonction hover de jQuery.

Dans les deux cas on passe à la fonction le paramètre "over" et "out" qui sont les référence aux fonctions qui gèrent l'état du menu.

En conclusion, je pense que le plus simple est de passer l'option "disableHI" à true et de remplacer "hover" par "toggle" dans la ligne de code en question.

$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'toggle'](over,out).each(function() {
    code executé 
}


De cette façon tu peux même te payer le luxe de pouvoir détecter en amont si l'utilisateur utilise un navigateur mobile ou non et remplacer en fonction l'évènement mouseover par click (option "disableHI").
Je te remercie, je vais travailler la dessus. J'avais déjà fait la recherche sur hover Intent mais je pensais pas qu'elle prenait le dessus sur superfich.