Hi Marco (I forwarded this also to the mailing list and removed the
picture as it wasn''t necessary to include to the mailing list so
everyone can hear the general techniques),
I recently had a very similar problem with my project. The problem
arises because whenever you move the mouse to ANY element, the previous
element that the mouse was over gets a mouseout event, even if it
happens to be a parent of the newly moused-over element. So it''s clear
that the mouse events don''t really keep track of parent-child
relationships, it''s either one element or another (not conditional
based
on the tree). So I think in your case, this is what''s happening,
although I could have completely misread the problem (so correct me if
I''m way off base).
So, there are two solutions that I came up with for this. You''ll have
to
figure out which one will work best for you. I am using them both in
different circumstances.
1) In the mouseout handler, check the event.toElement to see if
it''s a child element of the event.fromElement. If it is, take no
mouseout action. This might require you to have your element''s uniquely
id''ed with a predictable pattern. For instance, in my project, if a
parent div''s id is "Div1", all children elements''
id''s are as such;
"Div1_Child1", "Div1_Child2", etc.. Then in my mouseout
handlers I can
do something like this...
onMouseOut: function(event) {
if (event.toElement.id.lastIndexOf(event.fromElement.id) !-1) {
// do mouseout stuff
}
}
2) The other way is to use a timer mechanism instead of the
mouseout. This is a bit imperfect though, as you could potentially move
your mouse around within the same element for the duration of the timer
and it could still trigger the mouseout action. In this case, I use span
elements around my text to increase the number of elements within a div,
thus increasing the coincident number of mouseover events that can get
fired (thus resetting the timer mechanism). It also requires you to keep
track the mouseover state of your parent element. (Hopefully I''m using
descriptive enough variable names so you can figure out what you need to
do). You might use the Event.findElement() function in your case to get
the reference to myParentElement.
onMouseOver: function(event) {
if (!myParentElement.hasBeenMousedOver) {
// do mouseover stuff
myParentElement.hasBeenMousedOver = true;
setTimeout(this.countDown.bind(this), 1000); //
1 second
}
myParentElement.timer = 5; // adjust this to your
taste (1 second increments)
},
countdown: function() {
if (myParentElement.timer == 0) {
// do mouseout action
}
else {
myParentElement.timer--; // decrement the timer
setTimeout(this.countDown.bind(this), 1000); //
1 second
}
}
Finally, all this stuff is a bit easier if you define separate classes
to contain these "behaviors", and then extend your elements as needed
with those classes. I''d also keep handles to all your event listeners
so
you can dispose of them if needed (In a full fledged AJAX application
you have to handle breaking these circular references when they are no
longer needed, which is sometimes before the page unloads, otherwise
you''ll have nasty memory leaks). For instance, for a hover behavior
like
yours below, I''d do the following:
HoverClass = Class.create();
HoverClass.prototype = {
initialize: function() {
},
activate: function() {
this.mouseOverListener
this.onMouseOver.bindAsEventListener(this);
this.mouseOutListener
this.onMouseOut.bindAsEventListener(this);
Event.observe(this, "mouseover",
this.mouseOverListener);
Event.observe(this, "mouseout",
this.mouseOverListener);
},
onMouseOver: function (event) {
var element = Event.findElement(event,
''LI'');
Element.addClassName(element,
''btn-hover'');
},
onMouseOut: function (event) {
var element = Event.findElement(event,
''LI'');
Element.removeClassName(element,
''btn-hover'');
},
dispose: function() {
Event.stopObserving(this, "mouseover",
this.mouseOverListener);
Event. stopObserving (this, "mouseout",
this.mouseOverListener);
this.mouseOverListener = null;
this.mouseOutListener = null;
}
};
Then within whatever scope makes sense, you get a reference to your
element and extend it with the above class:
Object.extend(myElement, new HoverClass());
I hope some of this was helpful and that I at least touched on what
might be causing your problem...
________________________________
From: Marco M. Jaeger [mailto:mail-yVS5avHIROZWk0Htik3J/w@public.gmane.org]
Sent: Wednesday, January 11, 2006 1:24 PM
To: Ryan Gahl
Subject: FW: Event.observer - unordered list problems
Hello Ryan,
Just saw your post on the scriptaculous mailing list - maybe you can
help me with this one - unfortunately, I wasn''t able to post the whole
mail into the mailing list.
I''m having an unordered, relative positioned, list with some absolutely
positioned sub-lists. I hope the attached pictures can be seen on this
mailing list.
Unfortunately, using the Event.observer to create some onmouseout and
onmouseover events doesn''t lead to the expected result. The mouseover
effect is working but I''m not able to move over to the sub-list - it is
closed again as soon as I move off the main button.
This is the code I''m basically using:
addObservers: function (element) {
//Event.observe(element,
''mouseover'', this.onMouseOver.bindAsEventListener(this));
//Event.observe(element,
''mouseout'',
this.onMouseOut.bindAsEventListener(this));
Event.observe(element,
''mouseover'',
this.onMouseOver, false);
Event.observe(element,
''mouseout'',
this.onMouseOut, false);
},
onMouseOver: function (event) {
var element Event.findElement(event,
''LI'');
Element.addClassName(element,
''btn-hover'');
},
onMouseOut: function (event) {
var element Event.findElement(event,
''LI'');
Element.removeClassName(element,
''btn-hover'');
},
However, if I use something like this, everything is working fine:
element.onmousemove = function() {Element.addClassName(element,
''btn-hover'')};
element.onmouseout = function() {Element.removeClassName(element,
''btn-hover'')};
Does anybody know what I''m doing wrong?
The information transmitted in this electronic mail is intended only for the
person or entity to which it is addressed and may contain confidential,
proprietary, and/or privileged material. Any review, retransmission,
dissemination or other use of, or taking of any action in reliance upon,
this information by persons or entities other than the intended recipient
is prohibited. If you received this in error, please contact the sender and
delete the material from all computers.
_______________________________________________
Rails-spinoffs mailing list
Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs