11484 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour,

J'ai un problème sur un menu arborescent 3 niveaux :

Rubrique 1
Sous rub 1
Sous sous rub 11
Sous sous rub 12
Sous rub 2
Sous sous rub 22
Sous sous rub 21
Rubrique 2
....

Cacher / Montrer les sous rub en cliquant sur Rubrique 1 : pas de problème. Mais il faudrait que cela ne fasse apparaitre que les Sous rubrique.
Et faire pareil avec les sous sous rubrique : je clique sur sous rubrique et cela déplis les sous sous rubrique.

J'ai déja fait le code suivant mais je n'arrive pas à le faire sur le second niveau. LEs classes merde et cela ne cache / pas montre pas bien.

si vous aviez une soluce ce serait de la balle intégrale ! Smiley murf

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML
4.01 Transitional//EN">

<html>
<head>
<title>Untitled</title>

<style>

.menucoloroff .smenucoloroff {
display:none
}

.menucoloron .smenucoloroff {
display:block;
color:red;
}
</style>
<script>
var old_id = 0
var i = 0
function showhide (new_id) {
if (old_id==new_id) {
if (i == 2) {
document.getElementById('menu'+new_id).className = 'menucoloron'
old_id=new_id
i = 0
}
else {
document.getElementById('menu'+new_id).className = 'menucoloroff'
old_id=new_id
i = 2
}
}
else {
if (old_id ==0) {
old_id = new_id
document.getElementById('menu'+new_id).className = 'menucoloron'
}
else {
document.getElementById('menu'+old_id).className = 'menucoloroff';
document.getElementById('menu'+new_id).className = 'menucoloron';
old_id=new_id
}
}
}
</script>
</head>
<body>
<ul>
<li class="menucoloroff" id="menu1" style="cursor:pointer"
onclick="showhide(1)">Rub 1
<ul class="smenucoloroff">
<li>1
<ul>
<li>11</li>
<li>21</li>
</ul></li>
<li>2
<ul>
<li>11</li>
<li>21</li>
</ul>
</li>
</ul>
</li>
<li class="menucoloroff" id="menu2" style="cursor:pointer"
onclick="showhide(2)">Rub 2
<ul class="smenucoloroff">
<li>1</li>
<li>2</li>
</ul>
</li>
<li class="menucoloroff" id="menu3" style="cursor:pointer"
onclick="showhide(3)">Rub 3
<ul class="smenucoloroff">
<li>1</li>
<li>2</li>
</ul>
</li>
</ul>

</body>
</html>
ok, je jette un oeil sur ton blème, mais en attendant je trouve ça costaud de ne pas finir chaque ligne javascript avec un ";" vu le comportement très hasardeux que ça peut amener !
à plus,
Polo
Merci Polo,

Je ne savais pas qu'il fallait mettre des ; à la fin de chaque ligne.

Merci de ton aide et à tout de suite.
voici ma solution :


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>menu arborescent en liste</title>

<style type="text/css">
.menu ul {
  cursor:pointer;
}
.menu ul ul {
  display:none;
  color:red;
}
.menu ul ul ul {
  display:none;
  color:green;
}
</style>

<script type="text/javascript">
  function showhide(menu) {
    event.cancelBubble=true;
    menuStyle=menu.childNodes[1].style;
    menuStyle.display=(menuStyle.display=="block")? "none" : "block";
  }
</script>

</head>

<body>

<div class="menu">
<ul>
  <li onclick="showhide(this)">Rub 1
    <ul>
      <li onclick="showhide(this)">1
        <ul>
          <li>11</li>
          <li>21</li>
        </ul>
      </li>
      <li onclick="showhide(this)">2
        <ul>
          <li>21</li>
          <li>22</li>
        </ul>
      </li>
    </ul>
  </li>
  <li onclick="showhide(this)">Rub 2
    <ul>
      <li>1</li>
      <li>2</li>
    </ul>
  </li>
  <li onclick="showhide(this)">Rub 3
    <ul>
      <li>1</li>
      <li>2</li>
    </ul>
  </li>
</ul>
</div>

</body>

</html>

Attention, testé sur MSIE seulement ! (je pense particulièrement au "cancelBubble" qui doit se gérer différemment sous Netscape/Mozilla)

A plus,
Polo
Merci Polo, en effet il ne marche pas sous Mozilla Firefox. C'est con cela marchait parfaitement avec IE, pile les effets attendus.
Tu sais comment gérér ce problème sous Mozilla ?
Modifié le 10 Dec 2004 - 16:19
Ça devrait être bon avec ça:


function showhide(evt)
{
    var menuStyle = this.childNodes[1].style;
    menuStyle.display=(menuStyle.display=="block")? "none" : "block";
    
    if( evt )
        evt.stopPropagation();
    else
        window.event.cancelBubble = true;
}

window.onload = function() {
    var tmp = document.getElementById('menu').childNodes;
    for( var j = 0, m = tmp.length; j < m; j++ )
    {
        if( tmp[j].nodeType != 1 ) continue;
        tmp[j].onclick = showhide;
        
        for( var k = 0, n = tmp[j].childNodes.length; k < n; k++ )
        {
            if( tmp[j].childNodes[k].nodeType != 1 ) continue;
            tmp[j].childNodes[k].onclick = showhide;
        }
    }
};


Avec un id="menu" sur le premier élément UL.
En prime, tu n'as plus besoin de mettre les attributs 'onclick' directement sur tes éléments LI.

Quelques liens:
http://pompage.net/pompe/separation/
http://www.brainjar.com/dhtml/events/default.asp
Modifié le 10 Dec 2004 - 16:31
Non non, les évènements 'click' sont enregistrés directement dans le script.
(ex: tmp[j].onclick = showhide; )
Tu les mets pas, ils sont direct dans le code JavaScript.
Ca fait un truc du genre :
la solution de Bobe doit être sensiblement la même que la mienne :
http://www.elmoustikoblog.net/divers/menu/

function displayMenu()
{
	hideAll() ;
	var menu = document.getElementById('menu') ;
	var h2s = menu.getElementsByTagName('h2') ;
	
	for(var i = 0 ; i < h2s.length ; i++)
	{
		h2s[ i].onclick = function()
		{
			var cur_ul = this.parentNode.getElementsByTagName('ul')[0] ;
			if(cur_ul.style.display != "none")
			{
				hideAll() ;
			}
			else
			{
				hideAll() ;
				cur_ul.style.display = "" ;
			}
		}
	}
}

function hideAll()
{
	var menu = document.getElementById('menu') ;
	var uls = menu.getElementsByTagName('ul') ;
	for(var j = 0 ; j < uls.length ; j++ )
	{
		uls[j].style.display = "none" ;
	}
}

window.onload = displayMenu ;


-edit- grillé par Bobe Smiley cligne
Modifié le 10 Dec 2004 - 16:39
Je suis désolé messieurs mais je viens de tester les deux et cela ne marche pas.

J'ai viré les styles, viré les onclicks, mis le ID sur le premier UL et cela foire encore.
Bah, pour ma solution, c'est pas testé pour le 2eme sous niveau, ça doit être facilement adaptable, mais en tout cas tel quel, ça fonctionne, la preuve, le lien que je t'ai donné Smiley cligne !
Panique pas, mas puce, je vais te trouver le truc, et le tout avec un code RAISONNABLE.

Je rajoute ça pour ceux qui apparemment se foutent du nombre de lignes de code qu'ils balance sur le Net, pas moi !!!
Julio> t'as pas un exemple en ligne qu'on voit ce qui ne marche pas, qu'on puisse mieux t'aiguiller.
Non rien en ligne. Enfi le seul truc que j'ai c'est exactement le code du premier post. Rien de plus. J'arrive a cacher montrer le premier niveau mais pas à jouer avec le second niveau tout en gardant le premier ouvert.

en tout cas merci pour votre aide!

function showhide(evt)
{
    var menuStyle = this.childNodes[1].style;
    menuStyle.display=(menuStyle.display=="block")? "none" : "block";

    if( evt )
        evt.stopPropagation();
    else
        window.event.cancelBubble = true;
}

window.onload = function() {
    var tmp = document.getElementById('menu').childNodes;
    for( var j = 0, m = tmp.length; j < m; j++ )
    {
        if( tmp[j].nodeType != 1 ) continue;
        tmp[j].onclick = showhide;
        
        if( tmp[j].getElementsByTagName('ul').length == 0 ) continue;
        var tmp2 = tmp[j].getElementsByTagName('ul')[0];
        for( var k = 0, n = tmp2.childNodes.length; k < n; k++ )
        {
            if( tmp2.childNodes[k].nodeType != 1 ) continue;
            tmp2.childNodes[k].onclick = showhide;
        }
    }
};


Là, c'est fonctionnel, un petit oubli dans le code de mon précédent message.
Si on clique sur un item du troisième niveau, l'évènement click se produit aussi, mais bon, c'est inhérent à la structure du document actuel...

polothekid a écrit :

Je rajoute ça pour ceux qui apparemment se foutent du nombre de lignes de code qu'ils balance sur le Net, pas moi !!!


Ah, c'est sans doute mieux avec du code qui ne marche que sur un navigateur, et en parsemant le document d'attributs d'évènement qui n'ont rien à y faire ?
Mangez des carottes aussi, ça rend aimable.
Modifié le 10 Dec 2004 - 17:05
C'est génial ce script Smiley cligne
Néammoins il y a un petit probléme :
Quand on a un menu, en général c'est pour que la balise <li> contienne un lien qui nous envoie sur une autre page.
Or quand je place dans mes <li> des liens (balise <a>) le script ne marche plus Smiley biggol
Je ne comprends pas le javascript mais il me semble que ".childNodes" identifie un noeuds enfant (ou balise fille).
Donc dans le script javascript il ne fait plus référence à la balise fille <li> ou <ul> mais à la balise <a> Smiley bawling
Veuillez rectifier si me trompe et si vous avez une solution merci par avance et encore tous mes encouragements Smiley biggrin
Pages :