IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Menu déroulant avec temporisation avant ouverture


Sujet :

JavaScript

  1. #1
    Membre éclairé Avatar de xess91
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 408
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  2. #2
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    chez moi, ton script marche très bien;

  3. #3
    Membre Expert
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Par défaut
    Oui, le sous-menu s'ouvre aussi avec le deuxième exemple fourni... qu'est-ce qui "ne marche pas" pour toi ?

  4. #4
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    j'ai juste mis un doctype et des balises de script correctes;

  5. #5
    Membre Expert
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Par défaut
    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

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    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.

  7. #7
    Membre éclairé Avatar de xess91
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 408
    Par défaut
    exactement Nosmoking, c'est exactement le problème !!!

  8. #8
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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>

  9. #9
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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?

  10. #10
    Membre éclairé Avatar de xess91
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 408
    Par défaut
    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...

  11. #11
    Membre éclairé Avatar de xess91
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 408
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !

  12. #12
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    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

  13. #13
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    coquille ==> edit: "setTimeout n'admet pas de 3e param";

  14. #14
    Membre éclairé Avatar de xess91
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 408
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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!

  15. #15
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    en fait, si tu as défini dans la fonction

    this.param=param;

    je penses que tu peux essayer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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);
    }

  16. #16
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    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...

  17. #17
    Membre éclairé Avatar de xess91
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 408
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !

Discussions similaires

  1. [MySQL] Menu déroulant avec données sql
    Par matt38 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 08/08/2012, 23h40
  2. menu déroulant avec conio
    Par lastrecrue dans le forum C
    Réponses: 9
    Dernier message: 01/07/2006, 14h14
  3. [PHP-JS] Menu déroulant avec proposition de login
    Par xender dans le forum Langage
    Réponses: 1
    Dernier message: 16/05/2006, 14h08
  4. [PHP-JS] besoin d'aide pour menu déroulant avec lien
    Par Damarus dans le forum Langage
    Réponses: 3
    Dernier message: 06/10/2005, 18h43
  5. Menu déroulant avec préselection automatique
    Par Invité dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 16/06/2005, 12h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo