How do I check if the mouse is over an element in

2018-12-31 08:12发布

Is there a quick & easy way to do this in jQuery that I'm missing?

I don't want to use the mouseover event because I'm already using it for something else. I just need to know if the mouse is over an element at a given moment.

I'd like to do something like this, if only there was an "IsMouseOver" function:

function hideTip(oi) {
    setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}

24条回答
余欢
2楼-- · 2018-12-31 08:58

Just a note about the popular and helpful Arthur Goldsmith answer above: If you're moving your mouse from one element to another in IE (at least until IE 9) you may have some trouble getting this to work correctly if the new element has a transparent background (which it would by default). My workaround was the give the new element a transparent background image.

查看更多
栀子花@的思念
3楼-- · 2018-12-31 08:59

You can test with jQuery if any child div has a certain class. Then by applying that class when you mouse over and out out a certain div, you can test whether your mouse is over it, even when you mouse over a different element on the page Much less code this way. I used this because I had spaces between divs in a pop-up, and I only wanted to close the pop up when I moved off of the pop up, not when I was moving my mouse over the spaces in the pop up. So I called a mouseover function on the content div (which the pop up was over), but it would only trigger the close function when I moused-over the content div, AND was outside the pop up!


$(".pop-up").mouseover(function(e)
    {
    $(this).addClass("over");
    });

$(".pop-up").mouseout(function(e)
    {
    $(this).removeClass("over");
    });


$("#mainContent").mouseover(function(e){
            if (!$(".expanded").hasClass("over")) {
            Drupal.dhtmlMenu.toggleMenu($(".expanded"));
        }
    });

查看更多
查无此人
4楼-- · 2018-12-31 08:59

I combined ideas from this topic and came up with this, which is useful for showing/hiding a submenu:

$("#menu_item_a").mouseenter(function(){
   clearTimeout($(this).data('timeoutId'));
   $("#submenu_a").fadeIn("fast");
}).mouseleave(function(){
   var menu_item = $(this);

   var timeoutId = setTimeout(function(){
      if($('#submenu_a').is(':hover'))
      {
        clearTimeout(menu_item.data('timeoutId'));
      }
      else
      {
        $("#submenu_a").fadeOut("fast");
      }
   }, 650);

    menu_item.data('timeoutId', timeoutId); 
});

 $("#submenu_a").mouseleave(function(){
   $(this).fadeOut("fast");
 });

Seems to work for me. Hope this helps someone.

EDIT: Now realizing this approach is not working correctly in IE.

查看更多
闭嘴吧你
5楼-- · 2018-12-31 09:01

As I cannot comment, so I will write this as an answer!

Please understand the difference between css selector ":hover" and the hover event!

":hover" is a css selector and was indeed removed with the event when used like this $("#elementId").is(":hover"), but in it's meaning it has really nothing to do with the jQuery event hover.

if you code $("#elementId:hover"), the element will only be selected when you hover with the mouse. the above statement will work with all jQuery versions as your selecting this element with pure and legit css selection.

On the other hand the event hover which is

$("#elementId").hover(
     function() { 
         doSomething(); 
     }
); 

is indeed deprecaded as jQuery 1.8 here the state from jQuery website:

When the event name "hover" is used, the event subsystem converts it to "mouseenter mouseleave" in the event string. This is annoying for several reasons:

Semantics: Hovering is not the same as the mouse entering and leaving an element, it implies some amount of deceleration or delay before firing. Event name: The event.type returned by the attached handler is not hover, but either mouseenter or mouseleave. No other event does this. Co-opting the "hover" name: It is not possible to attach an event with the name "hover" and fire it using .trigger("hover"). The docs already call this name "strongly discouraged for new code", I'd like to deprecate it officially for 1.8 and eventually remove it.

Why they removed the usage is(":hover") is unclear but oh well, you can still use it like above and here is a little hack to still use it.

(function ($) {
   /** 
    * :hover selector was removed from jQuery 1.8+ and cannot be used with .is(":hover") 
    * but using it in this way it works as :hover is css selector! 
    *
    **/
    $.fn.isMouseOver = function() {
        return $(this).parent().find($(this).selector + ":hover").length > 0;
    };
})(jQuery);

Oh and I would not recomment the timeout version as this brings a lot of complexity, use timeout functionalities for this kind of stuff if there is no other way and believe me, in 95% percent of all cases there is another way!

Hope I could help a couple people out there.

Greetz Andy

查看更多
牵手、夕阳
6楼-- · 2018-12-31 09:01

I couldn't use any of the suggestions above.
Why I prefer my solution?
This method checks if mouse is over an element at any time chosen by You.
Mouseenter and :hover are cool, but mouseenter triggers only if you move the mouse, not when element moves under the mouse.
:hover is pretty sweet but ... IE

So I do this:

No 1. store mouse x, y position every time it's moved when you need to,
No 2. check if mouse is over any of elements that match the query do stuff ... like trigger a mouseenter event

// define mouse x, y variables so they are traced all the time
var mx = 0; //  mouse X position
var my = 0; //  mouse Y position

// update mouse x, y coordinates every time user moves the mouse
$(document).mousemove(function(e){
    mx = e.pageX;
    my = e.pageY;
});

// check is mouse is over an element at any time You need (wrap it in function if You need to)
$("#my_element").each(function(){
    boxX = $(this).offset().left;
    boxY = $(this).offset().top;
    boxW = $(this).innerWidth();
    boxH = $(this).innerHeight();
    if ((boxX <= mx) &&
        (boxX + 1000 >= mx) &&
        (boxY <= my) &&
        (boxY + boxH >= my))
    {
        // mouse is over it so you can for example trigger a mouseenter event
        $(this).trigger("mouseenter");
    }
});
查看更多
墨雨无痕
7楼-- · 2018-12-31 09:02

JUST FYI for future finders of this.

I made a jQuery plugin that can do this and a lot more. In my plugin, to get all elements the cursor is currently hovered over, simply do the following:

$.cursor("isHover"); // will return jQ object of all elements the cursor is 
                     // currently over & doesn't require timer

As I mentioned, it also has alot of other uses as you can see in the

jsFiddle found here

查看更多
登录 后发表回答