views:

143

answers:

3

Is there a function I can call to know if a certain element is currently being hovered over, like this?

/* Returns true or false */
hoveringOver("a#mylink");
+3  A: 

Yes, in classic JS:

document.getElementById("mylink").onmouseover = function() { alert("Hover!"); }
document.getElementById("mylink").onmouseout  = function() { alert("Out!"); }

in jQuery:

$('#mylink').mouseover(function() {
  alert("Hover!");
});
Pekka
This will not work correctly if the element has children.
SLaks
@Slaks true, your jQuery approach is better.
Pekka
$('a#mylink') would be the best practice.
dmanexe
I need to access the mouseover state from other functions, for any link that is a member of a certain class. What do you suggest?
Pieter
@dmanexe true, but the ID must be unique anyway so it doesn't really matter.
Pekka
@pieter what do you mean by "access the state"? Do you need some kind of an "on/off" flag? If that's what you mean, it's probably easiest to set that flag on the element directly. Also, can you use jQuery? Just to clear up the confusion, as sLaks's jQuery approach is better than mine.
Pekka
When I say "access the state", I mean whether the mouse is placed on the element or not. I need this to make pop-down menus. To ensure that they don't close too early or too late, I need to know when the mouse hasn't been hovering over the menu or the element that activated the menu for 1 second straight.
Pieter
@Pieter Anything speaking against SLak's approach? I think it does exactly what you need.
Pekka
Yes, I'm having difficulties applying the principle to what I'm trying to build. I'll add a comment below in a few minutes.
Pieter
+1  A: 

I have no idea if this would be the best way to do this but if you are using jquery, you could do something like this:

var hoveringOver = false;

$("a#myLink").bind("mouseenter", function(){
hoveringOver = true;
});

$("a#myLink").bind("mouseleave", function(){
hoveringOver = false;
});

function isHoveringOver(){
return hoveringOver;
}
Jon
This will not work correctly if the element has children. You need to handle `mouseenter` and `mouseleave`.
SLaks
@SLaks, thanks for the suggestion, I think I fixed it! I also learned something from your response to the question, very cool!
Jon
It still won't work correctly. You shouldn't be handling `mouseover` and `mouseout` at all.
SLaks
@SLaks, Thanks again! Hopefully it is correct now.
Jon
+4  A: 

You can use jQuery's hover method to keep track:

$(...).hover(
    function() { $.data(this, 'hover', true); },
    function() { $.data(this, 'hover', false); },
}).data('hover', false);

if ($(something).data('hover'))
    //Hovered!
SLaks
This is better if the element has children because you don't want to fire too many over/out events on a stack, but OP didn't specify JQuery. Additionally, it doesn't work with items absolutely positioned and stacked on top of each other--for that you need more sophisticated logic.
Plynx
@Plynx: Yes, but the jQuery approach is easiest by far.
SLaks
This seems like a good solution, but I have trouble accessing the data from other functions. $("div.menu").hover( function() { $.data(this, 'hover', true); alert($("div#menu1").data('hover')); // Debug }, function() { $.data(this, 'hover', false); alert($("div#menu1").data('hover')); // Debug }); The debug alert works fine here, but if I do it outside this code block it tends to mess up and produces `null` as a result. Any idea why?
Pieter
Until the first mouseenter, there won't be any data. Add `.data('hover', true)`, as in my edit.
SLaks
It is still not behaving as expected. I want an alert to be displayed when the 'hover' element changes, but that doesn't happen. I've uploaded the code for your convenience: http://labs.pieterdedecker.be/test/test.htm
Pieter
Hello? Anyone out there?
Pieter
@Pieter: You should use jQuery's `hover` method instead of your inline onmouseover/onmouseout handlers. Also, you should initialize the `hover` data to `false`, not `true`. (My mistake) However, your problem is that you're running the code before the content loads. Move your `<script>` block to the bottom of the page.
SLaks
That works, thank you.
Pieter