Forum Moderators: open
I attach an event to an UL onmouseout, but the event occur also when i go out from a child LI emement.
i write for you a semplificated version...in the real world i use some function to identificate the number of menu and dinamically extract the id name... but until here it works.
HTML:
at the top of the document:
<a id="product">.....</a>
....other anchorsin another place:
<ul id="mybeautifulmenu" >
<li id="imthefirst">
<ul id="nestedUL">
<li><a>....</a>
<li><a>....</a>
</ul>
</li>
.... other LI with nested UL
</ul>
There's a CSS that create a vertical menu where the LI element child of nestedUL and the A have the same dimension and location. The background of the A change by an :hover pseudo-class over the link.
The javascript:
obj=document.getElementById("nestedUL");
lnk=document.getElementById("product");lnk.onmouseover=function() { alert("Entering in "+this.attributes.id.nodeValue);}
obj.onmouseout= function() { alert("Exit from "+this.attributes.id.nodeValue);}
The purpose is to show the UL when i go over the link and hide it when i exit from the menu. I know that there are other methods to make this but i want to understand why this doesn't work as i expected.
OK the results..
the onmouseover of lnk object works well, the alert is:
// "Entering in product"
Also the the onmouseout works but also when i go out from a nested LI element, so when i pass from the first LI to the second, the text "exiting from nestedUL" appear. Obviously also when i exit from the UL(or maybe from the LI).
Why it happens? i've tried to attach the function to the "imthefirst" LI and the results are the same.
1. I don't understad if the unwanted event born in the LI or in the A elements...
2. If this is a problem of propagation why the event is propagated from the TOP to the BOTTOM and not vice-versa? (the event is store in the UL and react also in one of its child)...
Maybe are stupid questions...maybe i don't understand bubbling and capturing...
Thanks in advance
Ciao
Yuri
...maybe i don't understand bubbling and capturing...
You're not alone. Nor do I. I just get by.
IE uses event bubbling (event travels up the hierarchy).
Others can use bubbling, and capture (the opposite)
There are loads of ways to get round this, some browser specific. This is the one I go for (I find it simpler to grasp):
We have a global function that is assigned depending on which event model the browser is using. This should be placed anywhere at the top of the script:
getEventSrcElement = window.Event
? function(e){var targ=e.target;return targ.nodeType==1?targ:targ.parentNode}
: function() {return event.srcElement}
Then
obj.onmouseout= function(eMoz)
{
if( this!= getEventSrcElement(eMoz))
return false
// code for <UL> here
}
One problem that might arise is that the UL doesn't get receive any mouseouts of it's own (perhaps it has no 'margin' to be moused over).
there's a problem that i don't understand...the conditional
testvar = window.event? function() {alert("MOZ")} : function() {alert("IE")}
testvar();
give "IE" in Explorer and in Mozilla.
For me it's strange...
Is the window.event an IE object ,isn'i it?
So why the conditional is not inverted and in IE works?
And why Moz enter only in the second statement?
Seems that both the browsers don't pass the window.event condition.
so the script works only if i manually test it in Mozilla excluding the conditional and leaving intact only the function for Moz.
And you are right also for the margin problem. If i don't set a margin it doesn't work but if i set it it works...not as i expect...
the mouse enter in the border, and generated an event when exit from the border itself... also if i move the mouse over a LI, internal to the UL. Its behave like the UL is only the border part...like there is an hole in the UL... this make me frustrated because i use another time the wrong approach...
i think that i will use a fantastic CSS...
Your code it was very useful, thanks a lot.
window.Event This prevents "Event is undefined" error in IE. The condition could equally be:
typeof Event!= "undefined" ..but that's not as pretty!
So, your test code should be
testvar = window.Event? function() {alert("MOZ")} : function() {alert("IE")}
testvar(); You could amend it a little for a demonstration. Assigning the event handler in the way that we are, there will only be an event passed into the receiving function as an argument (eMoz) in the case of the 'standards' event model:
testvar = window.Event? function(eMoz) {alert("MOZ: "+eMoz)} : function(eMoz) {alert("IE: "+eMoz)}
testvar();