Comment puis-je différer la fermeture d'un menu ?

Index

Pour simplifier prenons le code de l'exemple d'un jQuery UI Menu. Nous avons le titre du menu dans un tag "a" et le menu lui-même dans un tag "ul". À l'ouverture de la page, le menu est caché. Le menu doit se montrer au survol de son titre et le menu doit se cacher lorsque l'utilisateur le quitte.

$( "#menu" ).menu();
	
$( "#titre" ).on( "mouseenter", function(){
	$( "#menu" ).fadeIn("slow");
});
 
$( "#menu" ).on( "mouseleave", function(){
	$( this ).fadeOut( "slow" );
});

Ce code est fonctionnel, mais à l'usage on constate rapidement que si l'utilisateur ne va pas sur le menu il ne se ferme jamais. Naturellement, on pense alors qu'il suffit de fermer le menu lorsque l'utilisateur quitte le titre. Mais il est impossible d'entrer dans le menu sans quitter le titre, donc une commande simple n'est pas possible. On doit programmer la fermeture du menu après un délai raisonnable et annuler cette programmation si l'utilisateur entre dans le menu.

Exemple

$( "#menu" ).menu();
 
var objMenuTimeout = null;
 
$( "#titre" ).hover(
	function(){
		$( "#menu" ).fadeIn( "slow" );
	},
	function(){
		objMenuTimeout = setTimeout( function(){
			$( "#menu" ).fadeOut( "slow" );
		}, 2000 ); // 2000 millisecondes = 2 secondes
	}
);
 
$( "#menu" ).hover(
	function(){
		clearTimeout( objMenuTimeout );
	},
	function(){
		$( this ).fadeOut( "slow" );
	}
);

La méthode hover() est l'équivalent d'un mouseenter() plus un mouseleave().

Tests unitaires avec QUnit.