Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript
JavaScript Forum programmation JavaScript. Lire : Cours JavaScript, FAQ JavaScript, Toutes les FAQ JavaScript et Sources JavaScript
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/03/2011, 21h35   #1
Membre actif
 
Avatar de xess91
 
Homme
Inscription : octobre 2008
Messages : 407
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 407
Points : 160
Points : 160
Par défaut Menu déroulant avec temporisation avant ouverture

Bonsoir à tous,

Je cherche à réaliser un menu déroulant en javascript qui s'ouvre qu'après avoir laisser la souris dessus pendant 200ms.

J'ai un problème de parent/enfant lors de la mise en place de la temporisation...

Je vous montre deux scripts le premier ou le sous-menu s'ouvre directement(fonctionne) et le deuxième ou le sous-menu s'ouvre après 200ms :

Ouverture direct (fonctionne):

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
<html>
 <head>
  <style>
   #menu { display: block; width: 100px; height: 30px; background: black; color: white; }
   #sous-menu { display: none; width: 100px; height: 100px; background: red; }  
  </style>
 </head>
<body>
<span id="menu">
 Menu
 <span id="sous-menu">
  sous-menu
 </span>
</span>
 
<script>
document.getElementById("menu").onmouseover = openMenu ;
document.getElementById("menu").onmouseout = closeMenu ;
 
function openMenu()
{
document.getElementById("sous-menu").style.display = "block" ;
}
 
function closeMenu()
{
document.getElementById("sous-menu").style.display = "none" ;
}
</script>
Ouverture temporisée (fonctionne pas):

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
<html>
 <head>
  <style>
   #menu { display: block; width: 100px; height: 30px; background: black; color: white; }
   #sous-menu { display: none; width: 100px; height: 100px; background: red; }  
  </style>
 </head>
<body>
<span id="menu">
 Menu
 <span id="sous-menu">
  sous-menu
 </span>
</span>
 
<script>
document.getElementById("menu").onmouseover = openMenu ;
document.getElementById("menu").onmouseout = closeMenu ;
 
var timer = null ;
 
function openMenu()
{
timer = setTimeout(goOpenMenu, 2000) ;
}
 
function goOpenMenu()
{
clearTimeout(timer) ;
timer = null ;
document.getElementById("sous-menu").style.display = "block" ;
}
 
function closeMenu()
{
document.getElementById("sous-menu").style.display = "none" ;
}
</script>
J'ai volontairement mis à 2000ms afin de bien voir le comportement des fonctions.
Merci à tous pour votre aide.
xess91 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 10h30   #2
Expert Confirmé
 
Avatar de javatwister
 
Homme
danseur
Inscription : août 2003
Messages : 2 667
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Calvados (Basse Normandie)

Informations professionnelles :
Activité : danseur

Informations forums :
Inscription : août 2003
Messages : 2 667
Points : 3 035
Points : 3 035
chez moi, ton script marche très bien;
javatwister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 11h48   #3
Expert Confirmé Sénior
 
Avatar de RomainVALERI
 
Homme Romain VALERI
POOête
Inscription : avril 2008
Messages : 2 572
Détails du profil
Informations personnelles :
Nom : Homme Romain VALERI
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : POOête

Informations forums :
Inscription : avril 2008
Messages : 2 572
Points : 4 073
Points : 4 073
Oui, le sous-menu s'ouvre aussi avec le deuxième exemple fourni... qu'est-ce qui "ne marche pas" pour toi ?
__________________

...pour les linguistes et les curieux >>> générateur de phrases aléatoires

__________________
RomainVALERI est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 11h58   #4
Expert Confirmé
 
Avatar de javatwister
 
Homme
danseur
Inscription : août 2003
Messages : 2 667
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Calvados (Basse Normandie)

Informations professionnelles :
Activité : danseur

Informations forums :
Inscription : août 2003
Messages : 2 667
Points : 3 035
Points : 3 035
j'ai juste mis un doctype et des balises de script correctes;
javatwister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 12h03   #5
Expert Confirmé Sénior
 
Avatar de RomainVALERI
 
Homme Romain VALERI
POOête
Inscription : avril 2008
Messages : 2 572
Détails du profil
Informations personnelles :
Nom : Homme Romain VALERI
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : POOête

Informations forums :
Inscription : avril 2008
Messages : 2 572
Points : 4 073
Points : 4 073
Citation:
Envoyé par javatwister Voir le message
j'ai juste mis un doctype et des balises de script correctes;
... et rajouté les /body et /html qui manquaient dans l'extrait ^^ on est d'accord... mais en tout cas le sous-menu s'ouvre bien
__________________

...pour les linguistes et les curieux >>> générateur de phrases aléatoires

__________________
RomainVALERI est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 14h08   #6
Modérateur
 
Avatar de NoSmoking
 
Homme
Inscription : janvier 2011
Messages : 2 933
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : janvier 2011
Messages : 2 933
Points : 4 757
Points : 4 757
Bonjour,
je note néanmoins un dysfonctionnement lorsque l'on glisse la mouse sur le sous menu ouvert, il y a disparition puis apparition.
Il y a en fait une succession de mouveover/mouseout qui s'enchaîne.
NoSmoking est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 22h31   #7
Membre actif
 
Avatar de xess91
 
Homme
Inscription : octobre 2008
Messages : 407
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 407
Points : 160
Points : 160
exactement Nosmoking, c'est exactement le problème !!!
xess91 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2011, 09h19   #8
Expert Confirmé
 
Avatar de javatwister
 
Homme
danseur
Inscription : août 2003
Messages : 2 667
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Calvados (Basse Normandie)

Informations professionnelles :
Activité : danseur

Informations forums :
Inscription : août 2003
Messages : 2 667
Points : 3 035
Points : 3 035
puisque tu en parles, il s'agirait plutôt de mettre un mouseout sur le sous-menu, histoire de pouvoir le consulter et sélectionner des choix...

en changeant un peu ton agencement, on obtient ça (c'est peut-être un début)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
 
<style type="text/css">
 
#cadre {overflow:hidden; width: 100px; height: 30px; background: black; color: white; }
#menu { width: 100px; height:30px;background: black; }  
#sous-menu { width: 100px; height: 100px;background: red; }  
 
</style>
 
 
</head>
 
<body>
 
 
<div id="cadre">
	<div id="menu">Menu</div>
	<div id="sous-menu">sous-menu</div>
</div>
 
<script type="text/javascript">
 
document.getElementById("menu").onmouseover = openMenu ;
document.getElementById("sous-menu").onmouseout = closeMenu ;
var timer = null ;
 
function openMenu(){
timer = setTimeout(goOpenMenu, 2000) ;
}
 
function goOpenMenu(){
clearTimeout(timer) ;
document.getElementById("cadre").style.height = "130px" ;
}
 
 
function closeMenu(){
document.getElementById("cadre").style.height = "30px" ;
}
 
</script>
 
 
</body>
</html>
javatwister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2011, 09h40   #9
Modérateur
 
Avatar de NoSmoking
 
Homme
Inscription : janvier 2011
Messages : 2 933
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : janvier 2011
Messages : 2 933
Points : 4 757
Points : 4 757
le soucis c'est que maintenant tu obtiens un clignotement lorsque tu glisses du sous menu vers le menu.

Pour résoudre le problème il faut mettre un setTimeout sur la fermeture avec un délai de 1, par exemple, juste pour retarder la fermeture et de penser à scratcher le timer à l'ouverture.

tu auras au final
Code html :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
 <head>
  <style type="text/css">
   #menu { display: block; width: 100px; height: 30px; background: black; color: white; }
   #sous-menu { display: none; width: 100px; height: 100px; background: red; }
  </style>
 </head>
<body>
<span id="menu">
 Menu
 <span id="sous-menu">
  sous-menu #1
 </span>
</span>
<script type="text/javascript">
var iTimer = null;
document.getElementById("menu").onmouseover = openMenu ;
document.getElementById("menu").onmouseout = closeMenu ;
 
function openMenu(){
  clearTimeout( iTimer) ;
  iTimer = setTimeout( function(){
    document.getElementById("sous-menu").style.display = "block" ;
  }, 2000);
}
 
function closeMenu(){
  iTimer = setTimeout( function(){
    document.getElementById("sous-menu").style.display = "none" ;
  }, 1);
}
</script>
</body>
</html>
ou encore une partie script plus propre!!
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
document.getElementById("menu").onmouseover = function(){
  clearTimeout( this.iTimer);
  this.iDelaiOver = 2000;
  this.iDelaiOut  = 1;
  this.iTimer = setTimeout( function(){
    document.getElementById("sous-menu").style.display = "block" ;
  }, this.iDelaiOver);
}
document.getElementById("menu").onmouseout = function(){
  this.iTimer = setTimeout( function(){
    document.getElementById("sous-menu").style.display = "none" ;
  }, this.iDelaiOut);
}
</script>
dernière chose pourquoi passer pas des SPAN?
NoSmoking est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2011, 13h04   #10
Membre actif
 
Avatar de xess91
 
Homme
Inscription : octobre 2008
Messages : 407
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 407
Points : 160
Points : 160
Merci NoSmoking,

Effectivement mettre un timer sur la fermeture puis le clear sur l'ouverture supprime la succession indésirable des fonctions.

J'ai eu un manque de lucidité , encore merci à vous tous !

P.S. Pour les spans c'est vraiment ce qui m'est venu au moment de la rédaction du post, ça aurait très bien pu être des ul li ou même des divs...
xess91 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2011, 15h30   #11
Membre actif
 
Avatar de xess91
 
Homme
Inscription : octobre 2008
Messages : 407
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 407
Points : 160
Points : 160
Je reviens avec une autre question, arf, il y a des périodes comme ça ou les connexions se font moins bien, lol:

Comment passer un paramètre dans le cas suivant à la fonction dans le setTimeout (le paramètre "param"):

Code :
1
2
3
4
5
6
7
 
function fonction(param)
{
 iTimer = setTimeout( function(param){
    document.getElementById(param).style.display = "none" ;
  }, iDelaiOut);
}
Merci à tous pour votre aide !
xess91 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2011, 16h25   #12
Expert Confirmé
 
Avatar de javatwister
 
Homme
danseur
Inscription : août 2003
Messages : 2 667
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Calvados (Basse Normandie)

Informations professionnelles :
Activité : danseur

Informations forums :
Inscription : août 2003
Messages : 2 667
Points : 3 035
Points : 3 035
en fait, il me semble que setInterval n'admet pas de 3e argument, contrairement à setInterval;

donc, soit tu passes par setInterval avec un seul passage dans la boucle et tu mets param en 3e argument;

euh... soit tu ruses, mais j'ai pas réfléchi comment
javatwister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2011, 16h44   #13
Expert Confirmé
 
Avatar de javatwister
 
Homme
danseur
Inscription : août 2003
Messages : 2 667
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Calvados (Basse Normandie)

Informations professionnelles :
Activité : danseur

Informations forums :
Inscription : août 2003
Messages : 2 667
Points : 3 035
Points : 3 035
coquille ==> edit: "setTimeout n'admet pas de 3e param";
javatwister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2011, 16h45   #14
Membre actif
 
Avatar de xess91
 
Homme
Inscription : octobre 2008
Messages : 407
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 407
Points : 160
Points : 160
Voici une version un peu plus abouti du système de sous-menu, pour l'instant je fais une horrible concaténation dans les datas du menu pour atteindre son sous-menu plutôt que d'utiliser un childnode.

De toute façon j'ai toujours un problème malgrès les conseils de NoSmoking qui ont bien corrigés le passage du menu au sous-menu mais j'ai maintenant un problème lors du passage d'un menu à un autre...(le sous-menu précédent ne se ferme pas tandis que le sous-menu en cours s'ouvre)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> 
 <head>
  <style type="text/css">
   #contener-menu { position: relative; }
   #menu1 { display: block; width: 100px; height: 30px; background: black; color: white; float: left; }
   #sous-menu1 { display: none; width: 100px; height: 100px; background: red; position: relative; }  
   #menu2 { display: block; width: 100px; height: 30px; background: black; color: white; float: left; }
   #sous-menu2 { display: none; width: 100px; height: 100px; background: red; position: relative; }  
  </style>
 </head>
<body>
<div id="contener-menu">
	<ul id="menu1">
		<li>Menu1
			<ul id="sous-menu1">
				<li>sous-menu1</li>
			</ul>
		</li>
	</ul>
	<ul id="menu2">
		<li>Menu2
			<ul id="sous-menu2">
				<li>sous-menu2</li>
			</ul>
		</li>
	</ul>
</div>
<script type="text/javascript">
function sousMenu()
	{
	this.menus = null ;
	this.elMenu = null ;
	this.elSsMenuOpen = null ;
	this.elSsMenuClose = null ;
	this.timer = null ;
	this.timeOpen = 200 ;
	this.timeClose = 10 ;
	}
 
sousMenu.prototype.configuration = function()
	{
	var object = this ;
	for(var i = 0; i < this.menus.length; i++)
		{
		this.elMenu = document.getElementById(this.menus[i]);
 
		this.elMenu.dataOpen = {
			objectOpen:this, 
			ssMenuOpen:"sous-"+this.menus[i],
			fnOpen: function() { object.openMenu(this.ssMenuOpen); }
			}
		this.elMenu.onmouseover = function(){ this.dataOpen.fnOpen(); } ;
 
		this.elMenu.dataClose = {
			objectClose:this, 
			ssMenuClose:"sous-"+this.menus[i],
			fnClose: function() { object.closeMenu(this.ssMenuClose); }
			}
		this.elMenu.onmouseout = function(){ this.dataClose.fnClose(); } ;
		}
	}
 
sousMenu.prototype.openMenu = function(ssMenu)
	{
	var object = this ;
	clearTimeout(this.timer) ;
	this.timer = null ;
 
	this.elSsMenuOpen = ssMenu ;
 
	this.timer = setTimeout(function(){ object.goOpenMenu() }, this.timeOpen) ;
	}
 
sousMenu.prototype.goOpenMenu = function()
	{
	document.getElementById(this.elSsMenuOpen).style.display = "block" ;
	}
 
sousMenu.prototype.closeMenu = function(ssMenu)
	{
	var object = this ;
 
	clearTimeout(this.timer) ;
	this.timer = null ;
 
	this.elSsMenuClose = ssMenu ;
 
	this.timer = setTimeout(function(){ object.goCloseMenu() }, this.timeClose) ;
	}
 
sousMenu.prototype.goCloseMenu = function()
	{
	document.getElementById(this.elSsMenuClose).style.display = "none" ;
	}
 
var menu = new sousMenu() ;
menu.menus = Array('menu1', 'menu2') ;
menu.configuration() ;
 
</script>
</body>
</html>
Merci à tous pour votre aide!
xess91 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2011, 16h48   #15
Expert Confirmé
 
Avatar de javatwister
 
Homme
danseur
Inscription : août 2003
Messages : 2 667
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Calvados (Basse Normandie)

Informations professionnelles :
Activité : danseur

Informations forums :
Inscription : août 2003
Messages : 2 667
Points : 3 035
Points : 3 035
en fait, si tu as défini dans la fonction

this.param=param;

je penses que tu peux essayer

Code :
1
2
3
4
5
6
7
8
function fonction(param){
 
this.param=param;
 
iTimer = setTimeout( function(){
    document.getElementById(this.param).style.display = "none" ;
  }, iDelaiOut);
}
javatwister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2011, 16h51   #16
Expert Confirmé
 
Avatar de javatwister
 
Homme
danseur
Inscription : août 2003
Messages : 2 667
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Calvados (Basse Normandie)

Informations professionnelles :
Activité : danseur

Informations forums :
Inscription : août 2003
Messages : 2 667
Points : 3 035
Points : 3 035
ce que tu décris est récurrent quand on travaille sur des événements "mouse";

même si l'effet te semble moins ergonomique, ne laisse pas tomber l'option "click" qui n'a presque que des avantages...
javatwister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2011, 16h55   #17
Membre actif
 
Avatar de xess91
 
Homme
Inscription : octobre 2008
Messages : 407
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 407
Points : 160
Points : 160
Lol on s'est croisé JavaTwister ! #14

Edit:

Je viens faire un truc tout simple pour régler le problème du post #14.

J'ai rajouté :

Code :
1
2
3
4
5
6
 
if(this.elSsMenuOpen == ssMenu)
	{
	clearTimeout(this.timer) ;
	this.timer = null ;
	}
dans la méthode openMenu. Maintenant reste plus qu'a mettre en place un système de lecture des noeuds enfants pour que l'objet fonctionne quelque soit la profondeur des sous-menus, et ça, c'est pas gagné pour moi...

Edit n°2:

Et hop un retour en arrière, je viens de constater une erreur de fonctionnement lors du passage successif de la souris aux points suivants:



C'est un véritable casse-tête cette histoire de sous-menu, je comprends mieux maintenant les adeptes de Jquery.

Visiblement il y a un problème dans le nettoyage des timer, je continue de creuser.

Je suis ouvert à toute proposition concernant ce fichu script de sous-menu !

Merci à tous pour votre aide !
xess91 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h04.


 
 
 
 
Partenaires

Hébergement Web