I just realized I made a mistake... in the first numbered solution, the != should be = ________________________________ From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Ryan Gahl Sent: Wednesday, January 11, 2006 2:28 PM To: mail-yVS5avHIROZWk0Htik3J/w@public.gmane.org; rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: [Rails-spinoffs] RE: Event.observer - unordered list problems 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