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 :

Sous menu qui disparait trop rapidement (onmouseouver)


Sujet :

JavaScript

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre exp�riment�
    Avatar de beegees
    Homme Profil pro
    D�veloppeur Web
    Inscrit en
    Mars 2004
    Messages
    3 610
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 50
    Localisation : Belgique

    Informations professionnelles :
    Activit� : D�veloppeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 3 610
    Par d�faut Sous menu qui disparait trop rapidement (onmouseouver)
    Bonjour tout le monde,

    J'ai un menu.

    Le dernier �l�ment de mon menu (Dossiers) devrait �tre d�roulant, j'ai donc ceci :

    http://www.vetecocquereaux.be

    Vous remarquerez que sur le onmouseover, le menu s'affiche, c'est ce que je veux.

    Sur le onmouseout, le menu disparait, c'est aussi ce que je veux.

    Par contre, je voudrais pouvoir s�lectionner le sous menu mais pas moyen, le menu disparait.

    Voici le code du dernier �l�ment du menu (Dossiers) :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <div class="btn" onmouseover="afficher_masque_sous_menu('afficher');" onmouseout="afficher_masque_sous_menu('masquer');" >
                    	<a href="#" onclick="div_centrale('liens_utiles');" class="btn">Dossiers</a>
                        <div id="sousmenu" style="display:none">
                        	<div class="btn">
                    			<a href="#" onclick="div_centrale('liens_utiles');" class="btn">Chiens</a>
                             </div>
                            <div class="btn">
                                <a href="#" onclick="div_centrale('liens_utiles');" class="btn">Chats</a>
                             </div>
                            <div class="btn">
                                <a href="#" onclick="div_centrale('liens_utiles');" class="btn">NAC</a>
                            </div>
                        </div> 
                    </div>
    Voici le code javascript :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function afficher_masque_sous_menu(action)
    {
    	if(action == 'afficher')
    	{
    		document.getElementById('sousmenu').style.display = 'block';	
    	}
    	else
    	{
    		document.getElementById('sousmenu').style.display = 'none';	
    	}
     
    }
    Je voudrais savoir si il serait possible de pouvoir s�lectionner le sous-menu et lorsque je quitte ce sous menu (ou le menu), le menu devrait alors disparaitre.

    Avez-vous une id�e ?

    Merci d'avance pour l'aide.

    beegees

  2. #2
    Expert confirm�
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 100
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activit� : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 100
    Par d�faut
    Bonsoir,
    tu connais relatedTarget ? (Ou toElement sous MSIE.) C�est une propri�t� sp�cifique aux �v�nements de � survol �. Le probl�me c�est qu�en l��tat des choses, tu n�y a pas acc�s car tu lies tes �v�nements avec des attributs HTML.

    Utilise les gestionnaires d��v�nements (une petite recherche dans les tutos de ce site ou sur Google).

    Si ton menu et ton sous-menu sont coll�s, il suffit de rajouter un test dans la fonction qui masque le menu, pour savoir si le relatedTarget est le sous-menu ou pas.

    Prends bien le temps de comprendre le principe des gestionnaires d��v�nements, tu en auras besoin, et en particulier au bouilonnement des �v�nements, car avec mouseover et mouseout �a joue souvent de mauvais tours ^^

    Je suis pas du genre � donner un code tout fait � quelqu�un qui ne cherche pas � comprendre. Faut mettre les mains dans le cambouis
    La FAQ JavaScript � Les cours JavaScript
    Touche F12 = la console → l�outil indispensable pour d�velopper en JavaScript !

  3. #3
    Expert confirm�
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 100
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activit� : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 100
    Par d�faut
    Rebonjour !
    Par �gard pour les internautes qui d�barquent ici via Google, je vais poste une r�ponse constructive, quand m�me (je me suis aper�u qu�il n�y avait pas de tuto sur les event listeners sur ce site)�

    Alors pour commencer, je mets en pi�ce jointe une petite framework de mon cru dont le simple but est de � lisser � les diff�rences entre MSIE et les autres navigateurs. Ce framework s�appelle Browser (non, ce n�est pas le boss dans Mario) et propose une fonction addListener qui d�clenche des events trafiqu�s pour avoir des propri�t�s standard m�me sous IE.

    Les propri�t�s qui nous int�ressent ici sont target et relatedTarget.

    Bien.

    Commen�ons par le code HTML. On va imaginer un menu simple � seulement un niveau, repr�sent� par des listes :

    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
    <ul class="menu" id="main-menu">
    	<li>Commodis</li>
    	<li>
    		Amici
    		<ul class="sub-menu">
    			<li>Indigno</li>
    			<li>Quem</li>
    		</ul>
    	</li>
    	<li>
    		Amicorum
    		<ul class="sub-menu">
    			<li>Qit</li>
    			<li>Fruantur</li>
    			<li>Aliquem</li>
    		</ul>
    	</li>
    </ul>

    Par souci d�am�lioration progressive, les sous-menus ne sont pas masqu�s, ils le seront seulement si JavaScript est activ�.

    Je passe les d�tails pour le CSS, on va simplement mettre le strict minimum :
    Code CSS : 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
    .menu, .sub-menu
    {
    	background: white;
    	border: solid 1px black;
    	list-style: none;
    	padding: 0;
    	width: 10em;
    }
    .sub-menu
    {
    	z-index: 100;
    }
    .menu li:hover
    {
    	background: silver;
    }
    .menu li
    {
    	position: relative;
    }
    .sub-menu
    {
    	position: absolute;
    	top: 0;
    	left: 7em;
    }

    Le script � pr�sent. On commence par la fonction d�initialisation, qui se d�clenche � l��v�nement load de la page. Dans un premier temps, on masque les sous-menus :
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    Browser.addListener(window, 'load', function windowLoad() {
    	var lists = document.getElementsByTagName('ul');
    	for (var i = 0, list; list = lists.item(i); i++) {
    		if (list.className == 'sub-menu') {
    			list.style.display = 'none';
    		};
    	};
    });

    Maintenant, il faut que les mouseover fassent appara�tre les �ventuels sous-menus. On pourrait attacher un �v�nement � chaque item de menu, mais il est plus int�ressant d�utiliser le principe de la d�l�gation d��v�nement : on surveille seulement le menu entier, et on examine le target de l�objet event pour savoir quand agir. Pour cette fonction, je commence par mettre � en cache � le target dans une variable locale, car je vais m�en servir plusieurs fois, et je place le code de la fonction dans un if pour qu�elle n�agisse que sur les items :
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Browser.addListener(window, 'load', function windowLoad() {
    	// …
     
    	var menu = document.getElementById('main-menu');
    	Browser.addListener(menu, 'mouseover', menuMouseover);
    });
     
    function menuMouseover( ev ) {
    	var target = ev.target;
    	if (target.tagName == 'LI') {
    		// … corps de la fonction
    	};
    };

    Chaque item n�a pas forc�ment un sous-menu, c�est pourquoi il faut en tester la pr�sence avant de l�afficher :
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    		var ulSet;
    		if (ulSet = li.getElementsByTagName('ul')) {
    			var submenu = ulSet.item(0);
    			submenu.style.display = 'block';
    		};
    C�est vrai, je ne suis pas oblig� de passer par des variables interm�diaires, mais avouez que c�est plus clair comme �a
    Voici la fonction enti�re :
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function menuMouseover( ev ) {
    	var target = ev.target;
    	if (target.tagName == 'LI') {
    		var ulSet = target.getElementsByTagName('ul');
    		if (ulSet.length) {
    			var submenu = ulSet.item(0);
    			submenu.style.display = 'block';
    		};
    	};
    };

    � ce stade, on a d�j� quelque chose d�int�ressant Mais voici le plus dur : g�rer le mouseout pour faire dispara�tre les sous-menus�
    On utilise toujours la d�l�gation :
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Browser.addListener(window, 'load', windowLoad() {
    	// …
     
    	Browser.addListener(menu, 'mouseout', menuMouseout);
    });
     
    function menuMouseout( ev ) {
    	var target = ev.target;
    	// …
    };
    L� vous allez me dire : il suffit d�agir seulement si le target est un sous-menu.
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    function menuMouseout( ev ) {
    	var target = ev.target;
    	if (target.className == 'sub-menu') {
    		target.style.display = 'none';
    	};
    };
    Hmm, pas si simple� Par exemple, si l�utilisateur fait des mouvement de souris rapides, le mouseout peut se produire directement entre l�item de sous-menu (<li>) et l�ext�rieur, sans passer par le sous-menu (<ul>). Vous voyez ce que je veux dire ?

    Nouvelle tentative :
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function menuMouseout( ev ) {
    	var target = ev.target;
    	if (target.className == 'sub-menu') {
    		target.style.display = 'none';
    	} else if (target.tagName == 'LI') {
    		var parent = target.parentNode;
    		if (parent.className == 'sub-menu') {
    			parent.style.display = 'none';
    		};
    	};
    };

    Et l�, c�est le drame ! �a dispara�t n�importe quand. C�est l� qu�on va avoir besoin de relatedTarget : si le relatedTarget est aussi un item de sous-menu, on ne masque pas le sous-menu. Il faut �galement pr�voir le cas o� on a des marges et o� on pourrait glisser sur le <ul> dans l�espace entre deux <li> (j�esp�re que vous suivez toujours)�
    Code JavaScript : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function menuMouseout( ev ) {
    	var target = ev.target;
    	if (target.className == 'sub-menu') {
    		target.style.display = 'none';
    	} else if (target.tagName == 'LI') {
    		var related = ev.relatedTarget;
    		var parent = target.parentNode;
    		if (parent.className == 'sub-menu'
    			&& related != parent
    			&& related.parentNode != parent)
    		{
    			parent.style.display = 'none';
    		};
    	};
    };
    Voil�, on a fait le plus dur. Reste plus qu�� agir aussi quand on quitte l�item du menu principal qui a ouvert le sous-menu, le cas �ch�ant, en testant l�existance de de sous-menu comme dans menuMouseover :
    Code JavaScript : 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
    function menuMouseout( ev ) {
    	var target = ev.target;
    	if (target.className == 'sub-menu') {
    		target.style.display = 'none';
    	} else if (target.tagName == 'LI') {
    		var related = ev.relatedTarget;
    		var parent = target.parentNode;
    		if (parent.className == 'sub-menu' 
    			&& related != parent
    			&& related.parentNode != parent)
    		{
    			parent.style.display = 'none';
    		} else if (parent.className == 'menu'
    			&& related.className != 'sub-menu'
    			&& related.parentNode.className != 'sub-menu')
    		{
    			var ulSet = target.getElementsByTagName('ul');
    			if (ulSet.length) {
    				var submenu = ulSet.item(0);
    				submenu.style.display = 'none';
    			};
    		};
    	};
    };

    �a fait un code assez indigeste avec tous ces if imbriqu�s, mais �a a le m�rite de marcher (Cela dit, c�est sans doute optimisable.)

    Voici le code final :
    Code JavaScript : 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
    Browser.addListener(window, 'load', function windowLoad() {
    	var lists = document.getElementsByTagName('ul');
    	for (var i = 0, list; list = lists.item(i); i++) {
    		if (list.className == 'sub-menu') {
    			list.style.display = 'none';
    		};
    	};
    	var menu = document.getElementById('main-menu');
    	Browser.addListener(menu, 'mouseover', menuMouseover);
    	Browser.addListener(menu, 'mouseout', menuMouseout);
    });
     
    function menuMouseover( ev ) {
    	var target = ev.target;
    	if (target.tagName == 'LI') {
    		var ulSet = target.getElementsByTagName('ul');
    		if (ulSet.length) {
    			var submenu = ulSet.item(0);
    			submenu.style.display = 'block';
    		};
    	};
    };
     
    function menuMouseout( ev ) {
    	var target = ev.target;
    	if (target.className == 'sub-menu') {
    		target.style.display = 'none';
    	} else if (target.tagName == 'LI') {
    		var related = ev.relatedTarget;
    		var parent = target.parentNode;
    		if (parent.className == 'sub-menu' 
    			&& related != parent
    			&& related.parentNode != parent)
    		{
    			parent.style.display = 'none';
    		} else if (parent.className == 'menu'
    			&& related.className != 'sub-menu'
    			&& related.parentNode.className != 'sub-menu')
    		{
    			var ulSet = target.getElementsByTagName('ul');
    			if (ulSet.length) {
    				var submenu = ulSet.item(0);
    				submenu.style.display = 'none';
    			};
    		};
    	};
    };


    Sinon sur la Toile on trouve des techniques de feignasses � base de timeouts pour retarder l�g�rement le masquage du sous-menu, afin de laisser le temps � la souris d�arriver dessus. Je trouve que �a manque de panache

    Bien entendu, je reste dispo pour les questions.

    La FAQ JavaScript � Les cours JavaScript
    Touche F12 = la console → l�outil indispensable pour d�velopper en JavaScript !

  4. #4
    Membre exp�riment�
    Avatar de beegees
    Homme Profil pro
    D�veloppeur Web
    Inscrit en
    Mars 2004
    Messages
    3 610
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 50
    Localisation : Belgique

    Informations professionnelles :
    Activit� : D�veloppeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 3 610
    Par d�faut
    Bonjour Watilin,

    Merci pour ta r�ponse.

    Cette derni�re me semble un peu "gonfl�e" par rapport au probl�me que je rencontre.

    En fait, mon sous-menu fonctionne maintenant mais comme d'habitude, ne fonctionne plus avec cette m.... de IE.

    J'ai donc un souci avec onmouseover et onmouseout qui ne semble pas fonctionne avec IE.

    Merci encore pour l'aide et si quelqu'un a une id�e, je suis preneur.

    bon WE.

    beegees

    PS: merci de rectifier ton premier post :

    Je suis pas du genre � donner un code tout fait � quelqu�un qui ne cherche pas � comprendre.
    Je n'ai jamais dis que je ne cherchais pas � comprendre !

  5. #5
    Expert confirm�
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 100
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activit� : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 100
    Par d�faut
    salut,
    �a ne t��tait pas personnellement adress�. C��tait juste pour expliquer pourquoi je n�ai pas donn� de code imm�diatement.

    La FAQ JavaScript � Les cours JavaScript
    Touche F12 = la console → l�outil indispensable pour d�velopper en JavaScript !

Discussions similaires

  1. Sous menu qui disparait quand on passe la souris dessus
    Par pasc06 dans le forum Mise en page CSS
    R�ponses: 5
    Dernier message: 09/12/2009, 07h23
  2. pb sous menu qui reste ouvert quand je d�place la souris
    Par mouna201 dans le forum G�n�ral JavaScript
    R�ponses: 9
    Dernier message: 17/02/2007, 14h26
  3. IE6 + menu qui disparait au contact d'un contenu
    Par PuppeT mAsTer dans le forum G�n�ral JavaScript
    R�ponses: 10
    Dernier message: 09/08/2006, 16h33
  4. [css sous ie] menu qui disparait qd clic sur precedent ...
    Par michaelbob dans le forum Mise en page CSS
    R�ponses: 4
    Dernier message: 22/02/2006, 14h37
  5. [CSS] Menu qui disparait derriere un champ
    Par Pepito dans le forum Mise en page CSS
    R�ponses: 4
    Dernier message: 06/09/2005, 10h03

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