Newsgroup: it.comp.lang.javascript
Titolo: Problemi menu in JQuery

Non so se mi sto perdendo in un bicchier d'acqua ma ho problemi a
realizzare un menu in JQuery: ero convinto fosse una cosa molto più
semplice.
Ho il classico menu strutturato dove gli elementi di primo livello
sono voci <li> di liste; i 
sottomenu sono gestiti come liste child, più o meno come indicato
sotto:
<div id="menuleft">
<ul id="button-3">
<li id="active-button-3"><a href="...">Item 1</a></li>
<li class="menu"><a href="#">Item 2</a>
	<ul class="sottomenu" id="sub1">
	<li><a href="#">Subitem 1</a></li>
	<li><a href="#">Subitem 2</a></li>
	<li><a href="#">Subitem 3</a></li>
	<li><a href="#">Subitem 4</a></li>
	</ul>
</li>
</ul>
I sottomenu hanno display:none attivato nel css
Il codice JQuery, come idea, attiva i  sottomenu all'evento
mouseenter; i sottomenu sono chiusi come da codice seguente.
$(document).ready(
		function(){ 
		$('li.sottomenu').hide();
		enableMenu();
	}
);
function enableMenu(){ 	$('li.menu').bind
('mouseenter', 'm', menuOn);				/* Attivo
subomenu se su voce menu principale*/
	$('li.menu').bind			('mouseleave', 	'm',
menuOff);			/* Attivo subomenu se su voce menu
principale*/
	$('ul.sottomenu').bind("mouseenter", 's', subMenuOn);
/* Disattivo submenu se su voce submenu */
	$('ul.sottomenu').bind("mouseleave", 	's', subMenuOff);
/* Disattivo submenu se su voce submenu */
}
function menuOn(e){ 
	e.stopPropagation();
	$('ul.sottomenu').hide();
	scrivi('menuOn ' + e.data);
	var subMenuId;
	subMenuId = $(this).find("ul").attr('id'); 
	$('#' + subMenuId ).show();		
	return false;
}
function menuOff(e){
	e.stopPropagation();
	scrivi('menuOff)<br>');
	return false;
}
function subMenuOn(e){ 
	e.stopPropagation();
	scrivi('subMenuOn ' + e.data);
	return false;
}
function subMenuOff(e){
	e.stopPropagation();
	$('ul.sottomenu').hide();
	scrivi('subMenuOff');	
	return false;
}
function scrivi(arg){ 
	$('#debug').html( $('#debug').html() + ' ' + arg );
}
La cosa funziona su FF funziona ma su IE non funziona affatto: è da un
po' che sto impazzendo in quanto all'apertura i sottomenu vengono
chiusi immediatamente nonostante lo stopPropagation. Se sostituisco
eventi mouseenter/mouseleave con eventi over e out il tutto smette di
funzionare anche su FF Ero convinto che il problema fosse il bubbling
degli eventi; in realtà il fatto che su IE gli eventi vengano lanciati
anche quando passo da un elemento <li> alla voce di menu figlio rende
il problema ingestibile: come faccio a sapere su quale elemento
avviene la transizione?
Ciao

 	e.stopPropagation();
vedi sopra: non serve preventDefault?
-- 
"La realtà è un'illusione causata dall'assenza di alcool."
									      A.

 semplice.
prova quello che ho realizzato su 
tuttapovo.it
parte javascript
$(document).ready(function(){
  $("ul.menu li")
  .prepend("&nbsp;")
  .hover(function(){$(this).addClass("attivo");},
function(){$(this).removeClass("attivo");})
  .children("a")
  .each(function(){
    $(this.parentNode).data("href", $(this).attr("href")).css("cursor",
"pointer").click(function(){ location.href=$(this).data("href"); });
    $(this).replaceWith($(this).html());
  })
  .end()
  .filter("li:has(ul)")
  .hover(function(){ var ul=$(this).children("ul").get(0); var
l=$(ul).data("livello"); 
      $("ul.menu ul:visible").not(ul).each(function(){ if
($(this).data("livello")==l) { $(this).hide(); } }); $(ul).data("chiudi",
false).show(); }, 
    function(){ var o=$(this).children("ul").data("chiudi", true).get(0);
setTimeout(function(){ if ($.data(o, "chiudi")) $(o).hide(); }, 1500); })
  .children("ul").css("cursor", "default").data("chiudi",
true).click(function(){return false;}).each(function(){
    $(this).data("livello", $(this).parents("li").length);
    if ($(this).parents("ul:first").hasClass("orizzontale")) {
$(this).before("<span><img src='/images/freccia.gif' alt='' border=0></span>");
}
    else { $(this).before("<span><img src='/images/frecciadx.gif' alt=''
border=0></span>"); }
  });
  $("a.esterno").attr("target","_blank");
});
parte css
ul.menu{
	width: 150px;
	padding: 0;
	margin: 0;
	background-color: #990000;
}
ul.menu li a{
	margin-left: 4px;
	color: white;
	text-decoration: none;
}
ul.orizzontale{
	width: 100%;
	height: 22px;
}
ul.menu li{
	padding: 0;
	margin: 0;
	width: 150px;
	border-bottom: 1px solid #730000;
	list-style-image: none;
	list-style-type: none;
	display: block;
	background-color: #990000;
	background-attachment: inherit;
	color: white;
	font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
	font-size: 8pt;
	line-height: 22px;
	position: relative;
	z-index: 0;
	letter-spacing: 0px;
}
ul.orizzontale li{
	float: left;
	width: auto;
	padding-right: 20px;
}
ul.orizzontale li ul li{
	float: none;
	width: 150px;
	padding-right: 0;
}
ul.menu li ul{
	width: 150px;
	padding: 0;
	margin: 0;
	display: none;
	position: absolute;
	left: 150px;
	top: 0;
	cursor: default;
}
ul.orizzontale li ul{
	top: 22px;
	left: 0;
}
ul.orizzontale li ul ul{
	left: 150px;
	top: 0;
}
ul.menu li span{
	position: absolute;
	right: 2px;
	top: 0;
}
ul.menu li.attivo{
	background-color: yellow;
	color: #990000;
}
Saluti. Carlo.
-- 
Puoi chiamarmi con Skype, il mio id e' carlonike
Vuoi un sicuro e gratuito programma per la tua posta?
http://www.pegasusmail.tk
 o 
http://www.pmail.com

 semplice.
 farei cosě
<ul id="menu">
<li class="active"><a href="...">Item 1</a></li>
<li><a href="#">Item 2</a>
 <ul>
 <li><a href="#">Subitem 1</a></li>
 <li><a href="#">Subitem 2</a></li>
 <li><a href="#">Subitem 3</a></li>
 <li><a href="#">Subitem 4</a></li>
 </ul>
</li>
</ul>
$(document).ready(
  function(){ 
  $('#menu li ul').hide();
  $('#menu li').hover(
    function(){
      $('ul', this).show(1000);
    },
    function(){
      $('ul', this).hide(1000);
    }
  }
);


 Saluti. Carlo.
mancava la chiusura della parentesi


Ciao Cristiano,
grazie per avermi risposto.
JQuery dovrebbe proprio azzerare le differenze tra i browser, e
dovrebbe farlo riallineando IE allo standard DOM. Questa è una delle
ragioni fondamentali per cui cerco di adottare un javascript framework
che semplifichi le cose, oltre che come strumento per accelerare lo
sviluppo. In particolare:
http://docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29
dice, a proposito di IE, "Fixed where necessary (IE)." mentre a
proposito di preventDefault, dice che event.preventDefault()  non
agisce sul bubbling (AFAIK) ma inibisce azioni standard per l'oggetto
quali, per esempio, seguire un link.
La tua percezione di codice FF only è giusta, ma è una caratteristica
by design in base al quale l'API standard è estesa a IE mediante
opportuni wrappers.
Ciao


 farei così


Ciao
ho verificato il tuo suggerimento e l'idea è molto buona: semplifica
notevolmente il codice facendo un uso assai migliore delle capacità di
selezione di Jqery rispetto a quanto avevo fatto io: il tutto è
decisamente un miglioramento, tuttavia non risolve il problema di
fondo. Ovvero:  immagina che nella resa grafica le voci del menu di
primo livello si sovrappongano parzialmente alle voci di menu di
secondo livello: due rettangoli parzialmente sovrapposti. Quello che
succede è la seguente cosa:
1. Quando il mouse è nella intersezione (nell'area coperta
contemporaneamente da) tra la voce di primo livello e le voci di
secondo livello la cosa funzione;
2. Quando il mouse esce dalla intersezione *sul lato dx*, ovvero
rimanendo nell'area del submenu ma uscendo dalla voce di primo
livello, il sottomenu si chiude subito
3. Quando il mouse *rimanendo nel sottomenu* scorre verso il basso
uscendo però dall'allineamento con le voci di primo livello, di buovo
il menu sparisce
Una cosa da impazzire.


 Una cosa da impazzire.
dammi il foglio stile che usi...


 dammi il foglio stile che usi...
questo funziona...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Untitled</title>
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
<script>
$(document).ready(
function(){ 
$('#menu li ul').hide();
$('#menu li').hover(
function(){
$('ul:first', this).show(); $(this).addClass("active");
},
function(){
$('ul:first', this).hide(); $(this).removeClass("active");
});
}
);
</script>
<style>
body{ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size:
8pt; }
ul#menu,ul#menu ul{ margin: 0; padding: 0; }
ul#menu li{ padding: 0; margin: 0; width: 150px; list-style-image: none;
list-style-type: none; display: block; background-color: #bbe5ff; line-height:
20px; height: 20px; }
ul#menu li ul li{ background-color: #ffffcc; }
ul#menu li.active{ background-color: #ff9900; }
</style>
</head>
<body>
<ul id="menu">
<li class="active"><a href="...">Item 1</a></li>
<li><a href="#">Item 2</a>
 <ul>
 <li><a href="#">Subitem 1</a></li>
 <li><a href="#">Subitem 2</a></li>
 <li><a href="#">Subitem 3</a></li>
 <li><a href="#">Subitem 4</a></li>
 </ul>
</li>
<li><a href="#">Item 3</a>
 <ul>
 <li><a href="#">Subitem 1</a></li>
 <li><a href="#">Subitem 2</a></li>
 <li><a href="#">Subitem 3</a></li>
 <li><a href="#">Subitem 4</a></li>
 </ul>
</li>
<li><a href="#">Item 4</a>
 <ul>
 <li><a href="#">Subitem 1</a></li>
 <li><a href="#">Subitem 2</a></li>
 <li><a href="#">Subitem 3</a></li>
 <li><a href="#">Subitem 4</a></li>
 </ul>
</li>
</ul>
</body>
</html>


Saluti. Carlo.
Scusa se non ti ho potuto rispondere prima .... questo � il CSS che mi
hanno passato. Secondo te potrebbe essere un problema a livello di
css?
#button-3
	{
	width:240px;
	margin:0 0 20px 0;
	padding:10px 0 0 0;
	text-transform:uppercase;	
	font-weight:bold;
	}
#button-3 a
	{
	display:block;
	text-decoration:none;
	padding:5px 10px;
	margin:0;
	background:#F8F8F8;
	color:#000;
	border-bottom: 1px solid #DBDBDB;
	}
#button-3 li.menu
	{
	display:inline;list-style-type:none;z-index:1;
	}
#button-3 a
	{
	height:auto!important;
	height:0;
	font-size:.7em;
	}
#button-3 a:link, 
#button-3 a:visited
	{
	background:#F8F8F8 url(../images/elenco.gif) 0  0 no-repeat;
	color:#000;
	padding-left:55px;
	}
#button-3 a:hover, 
#button-3 a:focus,
#button-3 a:active
	{
	background:#F8F8F8 url(../images/elenco-hover.gif) 0  0
no-repeat;
	color:#EF8A22;
	}
#button-3 #active-button-3 a
	{
	background:#E9E9E9 url(../images/elenco-active.gif) 0  0
no-repeat;
	color:#999999;list-style-type:none;
	}
#button-3 li.menu ul.sottomenu
	{
	margin:0;
	padding:0;
	border:1px solid #DBDBDB;
	text-transform:none;
	}
#button-3 li.menu ul.sottomenu li
	{
	list-style-type:none;position:relative;z-index:8;
	}
#button-3 li ul.sottomenu a
	{
	text-decoration:none;
	padding:3px;
	margin:0;
	background:#F8F8F8;
	color:#000; 
	}
#button-3 li.menu ul.sottomenu a:link, 
#button-3 li.menu ul.sottomenu a:visited
	{
	background:#F8F8F8;
	color:#000;
	}
#button-3 li.menu ul.sottomenu a:hover, 
#button-3 li.menu ul.sottomenu a:focus,
#button-3 li.menu ul.sottomenu a:active
	{
	background:#F8F8F8;
	color:#EF8A22;
	}
#menuleft #sub1, #menuleft #sub2, #menuleft #sub3, #menuleft #sub4,
#menuleft #sub5, #menuleft #sub6
	{
	display:none;
	position:absolute;
	left:210px;
	z-index:7;
	width:270px;
	}
#button-3 li.menu ul#sub1
	{	
	top:30px;
	}
#button-3 li.menu ul#sub2
	{	
	top:55px;
	}
#button-3 li.menu ul#sub3
	{	
	top:102px;
	}
#button-3 li.menu ul#sub4
	{	
	top:147px;
	left:225px;
	}
#button-3 li.menu ul#sub5
	{	
	top:193px;
	}
#button-3 li.menu ul#sub6
	{	
	top:263px;
	}