如何检查鼠标是否位于 jQuery 中的元素上?

发布于 2024-07-30 13:01:18 字数 276 浏览 7 评论 0 原文

有没有快速& 我缺少在 jQuery 中执行此操作的简单方法吗?

我不想使用鼠标悬停事件,因为我已经将其用于其他用途。 我只需要知道鼠标在给定时刻是否位于某个元素上。

我想做这样的事情,如果有一个“IsMouseOver”函数:

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

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(26

末骤雨初歇 2024-08-06 13:01:19

感谢你们俩。 在某些时候,我不得不放弃尝试检测鼠标是否仍在元素上方。 我知道这是可能的,但可能需要太多代码才能完成。

我花了一些时间,但我采纳了你们的建议,并想出了一些对我有用的东西。

这是一个简化的(但功能性的)示例:

$("[HoverHelp]").hover (
    function () {
        var HelpID = "#" + $(this).attr("HoverHelp");
        $(HelpID).css("top", $(this).position().top + 25);
        $(HelpID).css("left", $(this).position().left);
        $(HelpID).attr("fadeout", "false");
        $(HelpID).fadeIn();
    },
    function () {
        var HelpID = "#" + $(this).attr("HoverHelp");
        $(HelpID).attr("fadeout", "true");
        setTimeout(function() { if ($(HelpID).attr("fadeout") == "true") $(HelpID).fadeOut(); }, 100);
    }
);

然后,为了在某些文本上工作,这就是我所要做的:

<div id="tip_TextHelp" style="display: none;">This help text will show up on a mouseover, and fade away 100 milliseconds after a mouseout.</div>

This is a <span class="Help" HoverHelp="tip_TextHelp">mouse over</span> effect.

除了大量精美的 CSS 之外,这还允许一些非常好的鼠标悬停帮助工具提示。 顺便说一句,我需要鼠标移开时的延迟,因为复选框和文本之间的微小间隙会导致当您移动鼠标时帮助信息会闪烁。 但这就像一个魅力。 我还为焦点/模糊事件做了类似的事情。

Thanks to both of you. At some point I had to give up on trying to detect if the mouse was still over the element. I know it's possible, but may require too much code to accomplish.

It took me a little while but I took both of your suggestions and came up with something that would work for me.

Here's a simplified (but functional) example:

$("[HoverHelp]").hover (
    function () {
        var HelpID = "#" + $(this).attr("HoverHelp");
        $(HelpID).css("top", $(this).position().top + 25);
        $(HelpID).css("left", $(this).position().left);
        $(HelpID).attr("fadeout", "false");
        $(HelpID).fadeIn();
    },
    function () {
        var HelpID = "#" + $(this).attr("HoverHelp");
        $(HelpID).attr("fadeout", "true");
        setTimeout(function() { if ($(HelpID).attr("fadeout") == "true") $(HelpID).fadeOut(); }, 100);
    }
);

And then to make this work on some text this is all I have to do:

<div id="tip_TextHelp" style="display: none;">This help text will show up on a mouseover, and fade away 100 milliseconds after a mouseout.</div>

This is a <span class="Help" HoverHelp="tip_TextHelp">mouse over</span> effect.

Along with a lot of fancy CSS, this allows some very nice mouseover help tooltips. By the way, I needed the delay in the mouseout because of tiny gaps between checkboxes and text that was causing the help to flash as you move the mouse across. But this works like a charm. I also did something similar for the focus/blur events.

停顿的约定 2024-08-06 13:01:19

我经常看到超时用于此目的,但是在事件的上下文中,您不能像这样查看坐标吗?:

function areXYInside(e){  
        var w=e.target.offsetWidth;
        var h=e.target.offsetHeight;
        var x=e.offsetX;
        var y=e.offsetY;
        return !(x<0 || x>=w || y<0 || y>=h);
}

根据上下文,您可能需要在调用 areXYInside 之前确保 (this==e.target) (e).

仅供参考-我正在考虑在dragLeave处理程序中使用这种方法,以确认dragLeave事件不是通过进入子元素而触发的。 如果您不以某种方式检查您是否仍在父元素内,则可能会错误地执行仅在您真正离开父元素时才有意义的操作。

编辑:这是一个好主意,但效果不够一致。 也许需要一些小的调整。

I see timeouts used for this a lot, but in the context of an event, can't you look at coordinates, like this?:

function areXYInside(e){  
        var w=e.target.offsetWidth;
        var h=e.target.offsetHeight;
        var x=e.offsetX;
        var y=e.offsetY;
        return !(x<0 || x>=w || y<0 || y>=h);
}

Depending on context, you may need to make sure (this==e.target) before calling areXYInside(e).

fyi- I'm looking at using this approach inside a dragLeave handler, in order to confirm that the dragLeave event wasn't triggered by going into a child element. If you don't somehow check that you're still inside the parent element, you might mistakenly take action that's meant only for when you truly leave the parent.

EDIT: this is a nice idea, but does not work consistently enough. Perhaps with some small tweaks.

爱情眠于流年 2024-08-06 13:01:19

您可以使用 jQuery 测试任何子 div 是否具有特定的类。 然后,当您将鼠标悬停在某个 div 上并移出某个 div 时,通过应用该类,您可以测试鼠标是否位于该 div 上,即使您将鼠标悬停在页面上的其他元素上也是如此,这样可以减少代码量。 我使用它是因为弹出窗口中的 div 之间有空格,并且我只想在离开弹出窗口时关闭弹出窗口,而不是当我将鼠标移到弹出窗口中的空格上时关闭弹出窗口。 因此,我在内容 div 上调用了鼠标悬停函数(弹出窗口已结束),但只有当我将鼠标悬停在内容 div 上且位于弹出窗口之外时,它才会触发关闭函数!

$(".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"));
        }
    });

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"));
        }
    });

江湖彼岸 2024-08-06 13:01:19

这将是最简单的方法!

  function(oi) 
  {
   if(!$(oi).is(':hover')){$(oi).fadeOut(100);}
  }

This would be the easiest way of doing it!

  function(oi) 
  {
   if(!$(oi).is(':hover')){$(oi).fadeOut(100);}
  }
夏花。依旧 2024-08-06 13:01:19

这是一种不依赖 jquery 并使用本机 DOM matches 的技术 API。 它使用供应商前缀来支持可追溯到 IE9 的浏览器。 请参阅 caniuse.com 上的 matchesselector 了解完整详细信息。

首先创建 matchesSelector 函数,如下所示:

var matchesSelector = (function(ElementPrototype) {
var fn = ElementPrototype.matches ||
          ElementPrototype.webkitMatchesSelector ||
          ElementPrototype.mozMatchesSelector ||
          ElementPrototype.msMatchesSelector;

return function(element, selector) {
  return fn.call(element, selector);
};

})(Element.prototype);

然后,检测悬停:

var mouseIsOver = matchesSelector(element, ':hover');

Here's a technique which doesn't rely on jquery and uses the native DOM matches API. It uses vendor prefixes to support browsers going back to IE9. See matchesselector on caniuse.com for full details.

First create the matchesSelector function, like so:

var matchesSelector = (function(ElementPrototype) {
var fn = ElementPrototype.matches ||
          ElementPrototype.webkitMatchesSelector ||
          ElementPrototype.mozMatchesSelector ||
          ElementPrototype.msMatchesSelector;

return function(element, selector) {
  return fn.call(element, selector);
};

})(Element.prototype);

Then, to detect hover:

var mouseIsOver = matchesSelector(element, ':hover');
小伙你站住 2024-08-06 13:01:19

我已经在另一个问题中回答了这个问题,并提供了您可能需要的所有详细信息:

使用 jQuery 检测 IF 悬停在元素上(在撰写本文时有 99 个赞成票)

基本上,您可以执行以下操作:

var ishovered = oi.is(":hover");

仅当 oi 是包含单个元素的 jQuery 对象时才有效。 如果有多个元素匹配,则需要应用于每个元素,例如:

var hoveredItem = !!$('ol>li').filter(function() { return $(this).is(":hover"); });
                  // not .filter(':hover'), as we can't apply :hover on multiple elements

This was tested opening jQuery 1.7.

I have answered this in another question, with all details you may need:

Detect IF hovering over element with jQuery (has 99 upvotes at the time of writing)

Basically, you can do something like:

var ishovered = oi.is(":hover");

This works only if oi is a jQuery object containing a single element. If there are multiple elements matched, you need to apply to each element, for example:

var hoveredItem = !!$('ol>li').filter(function() { return $(this).is(":hover"); });
                  // not .filter(':hover'), as we can't apply :hover on multiple elements

This was tested starting jQuery 1.7.

毁梦 2024-08-06 13:01:19

这是一个可以帮助您检查鼠标是否位于元素内部的函数。 您唯一应该做的就是调用可以拥有与鼠标相关的实时事件对象的函数。 像这样的东西:

$("body").mousemove(function(event){
     element_mouse_is_inside($("#mycontainer", event, true, {});
});

您可以在 github 或帖子底部看到源代码:

https://github.com/mostafatalebi/ElementsLocator/blob/master/elements_locator.jquery.js

function element_mouse_is_inside  (elementToBeChecked, mouseEvent, with_margin, offset_object)
{
    if(!with_margin)
    {
        with_margin = false;
    }
    if(typeof offset_object !== 'object')
    {
        offset_object = {};
    }
    var elm_offset = elementToBeChecked.offset();
    var element_width = elementToBeChecked.width();
    element_width += parseInt(elementToBeChecked.css("padding-left").replace("px", ""));
    element_width += parseInt(elementToBeChecked.css("padding-right").replace("px", ""));
    var element_height = elementToBeChecked.height();
    element_height += parseInt(elementToBeChecked.css("padding-top").replace("px", ""));
    element_height += parseInt(elementToBeChecked.css("padding-bottom").replace("px", ""));
    if( with_margin)
    {
        element_width += parseInt(elementToBeChecked.css("margin-left").replace("px", ""));
        element_width += parseInt(elementToBeChecked.css("margin-right").replace("px", ""));
        element_height += parseInt(elementToBeChecked.css("margin-top").replace("px", ""));
        element_height += parseInt(elementToBeChecked.css("margin-bottom").replace("px", ""));
    }

    elm_offset.rightBorder = elm_offset.left+element_width;
    elm_offset.bottomBorder = elm_offset.top+element_height;

    if(offset_object.hasOwnProperty("top"))
    {
        elm_offset.top += parseInt(offset_object.top);
    }
    if(offset_object.hasOwnProperty("left"))
    {
        elm_offset.left += parseInt(offset_object.left);
    }
    if(offset_object.hasOwnProperty("bottom"))
    {
        elm_offset.bottomBorder += parseInt(offset_object.bottom);
    }
    if(offset_object.hasOwnProperty("right"))
    {
        elm_offset.rightBorder += parseInt(offset_object.right);
    }
    var mouseX = mouseEvent.pageX;
    var mouseY = mouseEvent.pageY;

    if(  (mouseX > elm_offset.left && mouseX < elm_offset.rightBorder)
        && (mouseY > elm_offset.top && mouseY < elm_offset.bottomBorder) )
    {
        return true;
    }
    else
    {
        return false;
    }
}

Here is a function which helps you check if the mouse is inside an element or not. The only thing you should do is to call the function where you can have a live mouse-associated EventObject. something like this:

$("body").mousemove(function(event){
     element_mouse_is_inside($("#mycontainer", event, true, {});
});

You can see the source code here in github or at the bottom of the post:

https://github.com/mostafatalebi/ElementsLocator/blob/master/elements_locator.jquery.js

function element_mouse_is_inside  (elementToBeChecked, mouseEvent, with_margin, offset_object)
{
    if(!with_margin)
    {
        with_margin = false;
    }
    if(typeof offset_object !== 'object')
    {
        offset_object = {};
    }
    var elm_offset = elementToBeChecked.offset();
    var element_width = elementToBeChecked.width();
    element_width += parseInt(elementToBeChecked.css("padding-left").replace("px", ""));
    element_width += parseInt(elementToBeChecked.css("padding-right").replace("px", ""));
    var element_height = elementToBeChecked.height();
    element_height += parseInt(elementToBeChecked.css("padding-top").replace("px", ""));
    element_height += parseInt(elementToBeChecked.css("padding-bottom").replace("px", ""));
    if( with_margin)
    {
        element_width += parseInt(elementToBeChecked.css("margin-left").replace("px", ""));
        element_width += parseInt(elementToBeChecked.css("margin-right").replace("px", ""));
        element_height += parseInt(elementToBeChecked.css("margin-top").replace("px", ""));
        element_height += parseInt(elementToBeChecked.css("margin-bottom").replace("px", ""));
    }

    elm_offset.rightBorder = elm_offset.left+element_width;
    elm_offset.bottomBorder = elm_offset.top+element_height;

    if(offset_object.hasOwnProperty("top"))
    {
        elm_offset.top += parseInt(offset_object.top);
    }
    if(offset_object.hasOwnProperty("left"))
    {
        elm_offset.left += parseInt(offset_object.left);
    }
    if(offset_object.hasOwnProperty("bottom"))
    {
        elm_offset.bottomBorder += parseInt(offset_object.bottom);
    }
    if(offset_object.hasOwnProperty("right"))
    {
        elm_offset.rightBorder += parseInt(offset_object.right);
    }
    var mouseX = mouseEvent.pageX;
    var mouseY = mouseEvent.pageY;

    if(  (mouseX > elm_offset.left && mouseX < elm_offset.rightBorder)
        && (mouseY > elm_offset.top && mouseY < elm_offset.bottomBorder) )
    {
        return true;
    }
    else
    {
        return false;
    }
}
﹂绝世的画 2024-08-06 13:01:19

扩展“Happytime harry”所说的内容,请务必使用 .data() jquery 函数来存储超时 id。 这样,当稍后在同一元素上触发“mouseenter”时,您可以非常轻松地检索超时 ID,从而消除工具提示消失的触发器。

Extending on what 'Happytime harry' said, be sure to use the .data() jquery function to store the timeout id. This is so that you can retrieve the timeout id very easily when the 'mouseenter' is triggered on that same element later, allowing you to eliminate the trigger for your tooltip to disappear.

小耗子 2024-08-06 13:01:19

您可以使用 jQuery 的 mouseenter 和 mouseleave 事件。 您可以在鼠标进入所需区域时设置一个标志,并在鼠标离开该区域时取消设置该标志。

You can use jQuery's mouseenter and mouseleave events. You can set a flag when the mouse enters the desired area and unset the flag when it leaves the area.

何以心动 2024-08-06 13:01:19

我结合了这个主题的想法并提出了这个,这对于显示/隐藏子菜单很有用:

$("#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");
 });

似乎对我有用。 希望这对某人有帮助。

编辑:现在意识到这种方法在 IE 中无法正常工作。

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.

音盲 2024-08-06 13:01:19

我无法使用上面的任何建议。
为什么我更喜欢我的解决方案?
此方法检查鼠标是否在您选择的任何时间位于某个元素上。
Mouseenter:hover 很酷,但是 mouseenter 仅在您移动鼠标时触发,而不是在元素在鼠标下方移动时触发。
:hover 非常可爱,但是...IE

所以我这样做:

否 1. 每次需要时移动鼠标时存储鼠标 x, y 位置,
否 2. 检查鼠标是否位于与查询匹配的任何元素上,执行操作...例如触发 mouseenter 事件

// 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");
    }
});

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");
    }
});
夜唯美灬不弃 2024-08-06 13:01:19

请注意上面流行且有用的 Arthur Goldsmith 答案:如果您将鼠标从 IE 中的一个元素移动到另一个元素(至少在 IE 9 之前),如果新元素具有透明背景(默认情况下)。 我的解决方法是为新元素提供透明的背景图像。

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.

|煩躁 2024-08-06 13:01:19
$(document).hover(function(e) {
    alert(e.type === 'mouseenter' ? 'enter' : 'leave');
});

FIDDLE

$(document).hover(function(e) {
    alert(e.type === 'mouseenter' ? 'enter' : 'leave');
});

FIDDLE

九八野马 2024-08-06 13:01:19

使用 evt.originalEvent.composedPath()

MouseEvent 给出鼠标最近与之交互的 HTMLElement 数组。 最后一个元素是最外层的(即它始终是Window)。

MouseEvent composedPath() 示例如下:

显示 HTML 元素数组的控制台

通过检查此数组中是否存在可点击元素,您将知道是否有鼠标悬停在特定元素上...

$(window).on("mouseup", onMouseUp);
const $someButton = $("a.yourButton");

function onMouseUp(evt) {
  const path = evt.originalEvent.composedPath();
  if(path.indexOf($someButton[0]) !== -1){
    // released mouse over button
  }else{
    // did not release mouse over button
  }
}

Use evt.originalEvent.composedPath()

MouseEvent gives an array of HTMLElement's the mouse recently interacted with. The last element is the outer-most (i.e. it's always Window).

MouseEvent composedPath() example below:

A console showing an array of HTML elements

By checking this array for the presence of your clickable element, you will know if there was a mouseup over a particuar element...

$(window).on("mouseup", onMouseUp);
const $someButton = $("a.yourButton");

function onMouseUp(evt) {
  const path = evt.originalEvent.composedPath();
  if(path.indexOf($someButton[0]) !== -1){
    // released mouse over button
  }else{
    // did not release mouse over button
  }
}
如梦亦如幻 2024-08-06 13:01:19

对于像我这样需要不依赖于浏览器鼠标悬停/输入/离开事件或悬停状态的答案的人。 我在主页滑块中遇到了一种情况,左右滑动单击区域可能会重叠(或有时完全覆盖)横幅中的 CTA 按钮 - 这使得所有以前的方法都无用(浏览器仅报告元素上的事件)最高 z 指数)。 我的任务是让点击事件更多地关注按钮而不是点击按钮时的横幅功能。

我的完整解决方案如下所示:

jQuery('.carousel-control-prev').on('click.testClick', function(e) {
    var bannerButtons = jQuery('.banner-content a');
    for (var i = 0; i < bannerButtons.length; i++) {
        if (isMouseOver(bannerButtons.eq(i), e)) {
            e.preventDefault();
            e.stopPropagation();
            bannerButtons[i].click();
        }
    }
});

function isMouseOver($el, e) {
    if ($el.is(':visible')) {
        var offset = $el.offset();
        var x = (e.pageX - offset.left);
        var y = (e.pageY - offset.top);
        if (x > 0 && x < $el.outerWidth() && y > 0 && y < $el.outerHeight()) {
            return true;
        }
    }
    return false;
}

这可能需要更多的工作和测试,但现在它可以满足我的需要 - 在本例中是拦截横幅左键单击,检查鼠标是否恰好位于 CTA 上按钮,如果有,请点击 CTA 而不是横幅导航。

我完全理解更好的解决方案是重新设计横幅区域,这样就根本不会发生这种情况,但设计超出了我的控制范围。

For those like me who needed an answer that didn't depend on browser mouse-over/enter/leave events or hover states. I had a situation in a home-page slider, the left and right slide click areas could overlap (or sometimes completely cover) the CTA buttons in the banner - this renders all those previous methods useless (browser only reports events on the element with the highest z-index). I was tasked with making the click event care more about the button than the banner functionality when the click is over the button.

My full solution looks like this:

jQuery('.carousel-control-prev').on('click.testClick', function(e) {
    var bannerButtons = jQuery('.banner-content a');
    for (var i = 0; i < bannerButtons.length; i++) {
        if (isMouseOver(bannerButtons.eq(i), e)) {
            e.preventDefault();
            e.stopPropagation();
            bannerButtons[i].click();
        }
    }
});

function isMouseOver($el, e) {
    if ($el.is(':visible')) {
        var offset = $el.offset();
        var x = (e.pageX - offset.left);
        var y = (e.pageY - offset.top);
        if (x > 0 && x < $el.outerWidth() && y > 0 && y < $el.outerHeight()) {
            return true;
        }
    }
    return false;
}

This could probably do with a little more work and testing, but for right now it does what I need - which in this case is intercepting the banner left click, checking if the mouse happens to be over a CTA button, and if it is, click the CTA instead of the banner nav.

I fully understand that the better solution would be redesign the banner area so this can't happen at all, but the design is outside my control.

诗化ㄋ丶相逢 2024-08-06 13:01:19

您可以在 jquery 中使用 is(':visible');
对于 $('.item:hover') 它也可以在 Jquery 中工作。

这是一个 htm 代码 snnipet :

    <li class="item-109 deeper parent">
<a class="root" href="/Comsopolis/index.php/matiers"><span>Matiers</span></a>
<ul>
<li class="item-110 noAff">
<a class=" item sousMenu" href="/Comsopolis/index.php/matiers/tsdi">
<span>Tsdi</span>
</a>
</li>
<li class="item-111 noAff">
<a class="item" href="/Comsopolis/index.php/matiers/reseaux">
<span>Réseaux</span>
</a>
</li>
</ul>
</li>

这是 JS 代码:

$('.menutop > li').hover(function() {//,.menutop li ul

    $(this).find('ul').show('fast');

},function() {
    if($(this).find('ul').is(':hover'))
    $(this).hide('fast');

});

 $('.root + ul').mouseleave(function() {
    if($(this).is(':visible'))
    $(this).hide('fast');

});

这就是我所说的:)

You can use is(':visible'); in jquery
And for $('.item:hover') it is working in Jquery also.

this is a htm code snnipet :

    <li class="item-109 deeper parent">
<a class="root" href="/Comsopolis/index.php/matiers"><span>Matiers</span></a>
<ul>
<li class="item-110 noAff">
<a class=" item sousMenu" href="/Comsopolis/index.php/matiers/tsdi">
<span>Tsdi</span>
</a>
</li>
<li class="item-111 noAff">
<a class="item" href="/Comsopolis/index.php/matiers/reseaux">
<span>Réseaux</span>
</a>
</li>
</ul>
</li>

and this is the JS Code :

$('.menutop > li').hover(function() {//,.menutop li ul

    $(this).find('ul').show('fast');

},function() {
    if($(this).find('ul').is(':hover'))
    $(this).hide('fast');

});

 $('.root + ul').mouseleave(function() {
    if($(this).is(':visible'))
    $(this).hide('fast');

});

this what i was talking about :)

淡忘如思 2024-08-06 13:01:18

干净优雅的悬停检查:

if ($('#element:hover').length != 0) {
    // do something ;)
}

A clean and elegant hover check:

if ($('#element:hover').length != 0) {
    // do something ;)
}
棒棒糖 2024-08-06 13:01:18

这段代码说明了我和 happytime harry 想要表达的意思。 当鼠标进入时,会出现一个工具提示,当鼠标离开时,会设置一个延迟使其消失。 如果鼠标在延迟触发之前进入相同的元素,那么我们会使用之前存储的数据在触发器关闭之前销毁触发器。

$("someelement").mouseenter(function(){
    clearTimeout($(this).data('timeoutId'));
    $(this).find(".tooltip").fadeIn("slow");
}).mouseleave(function(){
    var someElement = $(this),
        timeoutId = setTimeout(function(){
            someElement.find(".tooltip").fadeOut("slow");
        }, 650);
    //set the timeoutId, allowing us to clear this trigger if the mouse comes back over
    someElement.data('timeoutId', timeoutId); 
});

This code illustrates what happytime harry and I are trying to say. When the mouse enters, a tooltip comes out, when the mouse leaves it sets a delay for it to disappear. If the mouse enters the same element before the delay is triggered, then we destroy the trigger before it goes off using the data we stored before.

$("someelement").mouseenter(function(){
    clearTimeout($(this).data('timeoutId'));
    $(this).find(".tooltip").fadeIn("slow");
}).mouseleave(function(){
    var someElement = $(this),
        timeoutId = setTimeout(function(){
            someElement.find(".tooltip").fadeOut("slow");
        }, 650);
    //set the timeoutId, allowing us to clear this trigger if the mouse comes back over
    someElement.data('timeoutId', timeoutId); 
});
鹤仙姿 2024-08-06 13:01:18

警告:is(':hover') 在 jquery 1.8+ 中已弃用。 请参阅这篇文章获取解决方案.

您还可以使用此答案:https://stackoverflow.com/a/6035278/8843测试鼠标是否悬停在元素上:

$('#test').click(function() {
    if ($('#hello').is(':hover')) {
        alert('hello');
    }
});

WARNING: is(':hover') is deprecated in jquery 1.8+. See this post for a solution.

You can also use this answer : https://stackoverflow.com/a/6035278/8843 to test if the mouse is hover an element :

$('#test').click(function() {
    if ($('#hello').is(':hover')) {
        alert('hello');
    }
});
最后的乘客 2024-08-06 13:01:18

在鼠标移出时设置超时以淡出并将返回值存储到对象中的数据中。 然后onmouseover,如果数据中有值则取消超时。

删除淡出回调中的数据。

实际上,使用 mouseenter/mouseleave 更便宜,因为当子项 mouseover/mouseout 触发时,它们不会触发菜单。

Set a timeout on the mouseout to fadeout and store the return value to data in the object. Then onmouseover, cancel the timeout if there is a value in the data.

Remove the data on callback of the fadeout.

It is actually less expensive to use mouseenter/mouseleave because they do not fire for the menu when children mouseover/mouseout fire.

禾厶谷欠 2024-08-06 13:01:18

您可以使用 jQuery 的 hover 事件来手动跟踪:

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

if ($(something).data('hover'))
    //Hovered!

You can use jQuery's hover event to keep track manually:

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

if ($(something).data('hover'))
    //Hovered!
花想c 2024-08-06 13:01:18

我需要完全像这样的东西(在更复杂的环境中,并且带有大量“mouseenters”和“mouseleaves”的解决方案无法正常工作),所以我创建了一个小jquery插件,添加了ismouseover方法。 到目前为止,效果非常好。

//jQuery ismouseover  method
(function($){ 
    $.mlp = {x:0,y:0}; // Mouse Last Position
    function documentHandler(){
        var $current = this === document ? $(this) : $(this).contents();
        $current.mousemove(function(e){jQuery.mlp = {x:e.pageX,y:e.pageY}});
        $current.find("iframe").load(documentHandler);
    }
    $(documentHandler);
    $.fn.ismouseover = function(overThis) {  
        var result = false;
        this.eq(0).each(function() {  
                var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
                var offset = $current.offset();             
                result =    offset.left<=$.mlp.x && offset.left + $current.outerWidth() > $.mlp.x &&
                            offset.top<=$.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
        });  
        return result;
    };  
})(jQuery);

然后在文档的任何地方你可以这样调用它,它会返回 true 或 false:

$("#player").ismouseover()

我在 IE7+、Chrome 1+ 和 Firefox 4 上测试了它并且工作正常。

I needed something exactly as this (in a little more complex environment and the solution with a lot of 'mouseenters' and 'mouseleaves' wasnt working properly) so i created a little jquery plugin that adds the method ismouseover. It has worked pretty well so far.

//jQuery ismouseover  method
(function($){ 
    $.mlp = {x:0,y:0}; // Mouse Last Position
    function documentHandler(){
        var $current = this === document ? $(this) : $(this).contents();
        $current.mousemove(function(e){jQuery.mlp = {x:e.pageX,y:e.pageY}});
        $current.find("iframe").load(documentHandler);
    }
    $(documentHandler);
    $.fn.ismouseover = function(overThis) {  
        var result = false;
        this.eq(0).each(function() {  
                var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
                var offset = $current.offset();             
                result =    offset.left<=$.mlp.x && offset.left + $current.outerWidth() > $.mlp.x &&
                            offset.top<=$.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
        });  
        return result;
    };  
})(jQuery);

Then in any place of the document yo call it like this and it returns true or false:

$("#player").ismouseover()

I tested it on IE7+, Chrome 1+ and Firefox 4 and is working properly.

沫雨熙 2024-08-06 13:01:18

在 jQuery 中,您可以使用 .is(':hover'),因此

function IsMouseOver(oi)
{
   return $(oi).is(':hover');
}

现在是提供 OP 中请求的功能的最简洁的方法。

注意:上述内容在 IE8 或更低版本中不起作用

作为在 IE8 中起作用的不太简洁的替代方案(如果我可以信任 IE9 的 IE8 模式),并且不会触发 $(... ).hover(...) 遍布各处,也不需要知道元素的选择器(在这种情况下,Ivo 的答案更容易):

function IsMouseOver(oi)
{
    return oi.length && 
           oi.parent()
             .find(':hover')
             .filter(function(s){return oi[0]==this})
             .length > 0;
}

In jQuery you can use .is(':hover'), so

function IsMouseOver(oi)
{
   return $(oi).is(':hover');
}

would now be the most concise way to provide the function requested in the OP.

Note: The above does not work in IE8 or lower

As less succinct alternative that does work in IE8 (if I can trust IE9's IE8 modus), and does so without triggering $(...).hover(...) all over the place, nor requires knowing a selector for the element (in which case Ivo's answer is easier):

function IsMouseOver(oi)
{
    return oi.length && 
           oi.parent()
             .find(':hover')
             .filter(function(s){return oi[0]==this})
             .length > 0;
}
厌味 2024-08-06 13:01:18

我采纳了 SLAks 的想法,并将其封装在一个小类中。

function HoverWatcher(selector){
  this.hovering = false;
  var self = this; 

  this.isHoveringOver = function() { 
    return self.hovering; 
  } 

    $(selector).hover(function() { 
      self.hovering = true; 
    }, function() { 
      self.hovering = false; 
    }) 
} 

var box1Watcher = new HoverWatcher('#box1');
var box2Watcher = new HoverWatcher('#box2');



$('#container').click(function() {
  alert("box1.hover = " + box1Watcher.isHoveringOver() +
        ", box2.hover = " + box2Watcher.isHoveringOver());
});

I took SLaks' idea and wrapped it in a small class.

function HoverWatcher(selector){
  this.hovering = false;
  var self = this; 

  this.isHoveringOver = function() { 
    return self.hovering; 
  } 

    $(selector).hover(function() { 
      self.hovering = true; 
    }, function() { 
      self.hovering = false; 
    }) 
} 

var box1Watcher = new HoverWatcher('#box1');
var box2Watcher = new HoverWatcher('#box2');



$('#container').click(function() {
  alert("box1.hover = " + box1Watcher.isHoveringOver() +
        ", box2.hover = " + box2Watcher.isHoveringOver());
});
梦断已成空 2024-08-06 13:01:18

仅供未来发现者参考。

我制作了一个 jQuery 插件,可以做到这一点以及更多。 在我的插件中,要获取光标当前悬停在其上的所有元素,只需执行以下操作:

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

正如我所提到的,它还有很多其他用途,如您在

在这里找到 jsFiddle< /a>

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

恬淡成诗 2024-08-06 13:01:18

由于我无法发表评论,所以我将写此作为答案!

请理解css选择器“:hover”和hover事件的区别!

":hover" 是一个 css 选择器,当像这样使用 $("#elementId").is(":hover") 时,确实会随事件一起删除,但就其含义而言,它实际上什么都没有与 jQuery 事件悬停有关。

如果您编写 $("#elementId:hover") 代码,则仅当您将鼠标悬停时才会选择该元素。 上面的语句适用于所有 jQuery 版本,因为您使用纯合法的 css 选择来选择此元素。

另一方面,悬停事件

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

确实在 jQuery 1.8 中已被弃用,这里来自 jQuery 网站的状态:

当使用事件名称“hover”时,事件子系统将其转换
事件字符串中的“mouseenter mouseleave”。 这很烦人
几个原因:

语义:悬停与鼠标进入和离开不同
一个元素,它意味着在之前有一定程度的减速或延迟
射击。 事件名称:附加处理程序返回的 event.type 是
不是悬停,而是 mouseenter 或 mouseleave。 没有其他事件可以做到这一点
这。 共同选择“hover”名称:无法附加
名为“hover”的事件并使用 .trigger(“hover”) 触发它。 这
文档已经称这个名字为“强烈不鼓励使用新代码”,我会
希望在 1.8 版本中正式弃用它并最终将其删除。

为什么他们删除了 is(":hover") 用法尚不清楚,但是哦,好吧,你仍然可以像上面一样使用它,这里有一个小技巧可以继续使用它。

(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);

哦,我不会推荐超时版本,因为这带来了很多复杂性,如果没有其他方法,请使用超时功能来处理这种事情,相信我, 95% 的情况都有另一种方法

希望我能帮助一些人。

格雷兹·安迪

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文