2

Okay, so, I have a bit of a strange situation which I have encountered multiple times. I'm looking for a simple/the best solution, NOT the overcomplicated solution I used before (and have since forgotten).

You see, I have a slideshow. I also have a couple of buttons that float on top of the slide show (visible here: http://marsxplr.com/view-13378)

Now, I have these buttons appear when the user's mouse goes over the slideshow. However, the minute the user's mouse goes over the buttons, mouseleave is called (even though the mouse is still technically over the slideshow!). This causes the buttons to disappear whenever the mouse goes over them, which is obviously not something I would like to happen.

I solved this by then making each button re-show its self whenever it receives a mouseover.

But now, we have a problem...

The button is on the very edge of the slideshow. That means that when mouseleave is called, one of two things happened:

A:The mouse went off of the button but not off of the slideshow, and mouseEnter got called on the slideshow meaning that no action should be taken because slideshow will eventually take care of hiding the button in its mouseleave.

B: The mouse simply left the slideshow and button altogether meaning that we should HIDE the button!

So my question is, how do I tell the difference between these two possibilities? Yes, yes, one solution would be to just always make the button hide its self -- and rely on the slideshow re-showing the button... But I am worried that the slideshow onmouseenter will be called BEFORE the button onmouseleave on certain browsers! This could cause issues as you can probably tell. In fact, thinking about this, I am already susceptible to this. For instance, if the mouse goes from the slideshow to the button, and the onmouseleave for my slideshow is called AFTER the onmousleave causing the button to still dissapear...

So, long story short, I need to know one of these two things:

  • Is there a guaranteed order in which these events are called?
  • Or is there a way to tell where the mouse actually WENT when mouseleave is called?

As you can see in my example above, I am using mootools, so a mootools solution is fine. It would, however, be interesting to see a vanilla-js solution as well.

EDIT: My buttons are floated and on a separate z-index, so the standard operation for a parent-child DOM relationship does not occur

Georges Oates Larsen
  • 6,812
  • 12
  • 51
  • 67

1 Answers1

2

No such problem with standard DOM events.

As for the order, it bubbles from the deepest elements up to the document root.

There's also an optional (see the false param in the code below) capture phase, when the order is reversed. From the root to each inner element under the cursor (for mouse events).

To check on which inner element of the original element the event actually occurred, you can inspect the target property of the event object:

el.addEventListener('mouseout', function (e) {
    var target = e.target;
    if (target.classList.contains('whatever')) {
        // Do something
    }
}, false);

As per Georges Oates Larsen's comment, there's also relatedTarget, designed specifically for events involving several elements.

katspaugh
  • 17,449
  • 11
  • 66
  • 103
  • I think my problem may be that my button (an img element) is floated and on a separate z-index -- not actually "inside" the slideshow (which is just a div with some fancy scrolling) Thank you for letting me know about the order. I am definitely having this problem, so do you know a solution to it? – Georges Oates Larsen Sep 12 '12 at 07:36
  • Ahhh this works perfectly, thankyou very much! +1 for the answer answering both questions :) – Georges Oates Larsen Sep 12 '12 at 07:44
  • @GeorgesOatesLarsen, I see. So your case is like this one: http://jsfiddle.net/qew4q/. There's no way to "let through" the event. It's always gonna flicker, unless you use a common container. You're welcome, anyway! – katspaugh Sep 12 '12 at 07:47
  • I am sorry, I spoke too soon and misread your answer -- It turns out that e.target is just returning the button -- I am very sorry to remove the "answered" status. YES! that is very similar to my problem, strikingly so actually :( Is there a way to get where the mouse WENT when mouseleave is called? hmm – Georges Oates Larsen Sep 12 '12 at 08:08
  • 1
    Oooohhhh! I found it! I wanted relatedTarget all along! :) Grr google not giving me any results, I had to manually use reflection to print out all of the event variable's "attributes" (am I calling them the right thing?) mouseleave: function(e) { alert(e.relatedTarget.get("class")); } Worked like a charm :) I will accept your answer, but perhaps you should add relatedTarget to it! :) – Georges Oates Larsen Sep 12 '12 at 08:22
  • 1
    @GeorgesOatesLarsen, added. Never known and used `relatedTarget` myself, so it's been very interesting to learn, thanks! – katspaugh Sep 12 '12 at 08:55