如何检查光标是否悬停在一个元素上?

22
我该如何使用JQuery/Javascript检查光标是否停留在HTML页面上的
元素上?
我想获取光标坐标并判断它们是否在我的元素矩形内。也许有预定义的方法吗?
更新:不要提到hover事件等,我需要一些像这样针对页面上某个元素返回真/假的方法:
var result = underElement('#someDiv'); // true/false

无论你想要什么,hover都是跨浏览器的选择,mouseovermouseenter是最简单的跨浏览器方式来跟踪悬停的元素。此外,你的措辞有点不对,鼠标从未在元素“下方”,而是在其“上方”。 - Nick Craver
如果您不使用悬停,您如何知道鼠标进入了您的那个框?... - Reigel Gallarde
1
@Reigel,请查看鼠标坐标并查看div位置。 - Max Frai
我为此贡献了一个伪表达式,希望能对某些人有所帮助。 - Alexander
@NickCraver:检查光标坐标有时是必要的。例如,如果您添加了一个位于光标下方的元素,则在用户移动鼠标之前,mouseover/mouseenter事件不会在该元素上触发。 - Roy Tinker
无法添加完整答案,因为问题已关闭,但可以尝试基于返回的对象进行操作:document.querySelectorAll(":hover"); - Lorien Brune
5个回答

11

我不太确定为什么你这么想避免鼠标悬停: 请考虑以下脚本

$(function(){

    $('*').hover(function(){
        $(this).data('hover',1); //store in that element that the mouse is over it
    },
    function(){
        $(this).data('hover',0); //store in that element that the mouse is no longer over it
    });


    window.isHovering = function (selector) {
        return $(selector).data('hover')?true:false; //check element for hover property
    }
});
基本上这个想法是使用hover来设置一个标志,该标志表示鼠标当前是否悬停在元素上。然后编写一个函数来检查该标志。

3
我非常喜欢这个解决方案。不过你最后只需要加上return $(selector).data('hover');就可以了,对吗? - fearofawhackplanet
2
这不是一个完整的答案:你如何一开始就初始化'hover'?在指针进入或退出元素边界之前,'hover'是未知的。 - worldsayshi
啊,我的错;为了解决这个问题,在初始化时假设指针在元素外部。'hover'将在指针移动到元素上时被触发,而不仅仅是在进入时触发。虽然这仍然留下了一个非常小的情况,即需要知道指针在初始化时的位置而不移动它。但这不是我的问题。 - worldsayshi
这就是我缺失的该死的拼图。加上mouseleave而不是mouseout,我感觉我开始掌握悬停事件了。 - Félix Adriyel Gagnon-Grenier
你可能想要对这些函数进行节流,因为在实现大量元素的页面上可能会导致性能问题。*选择器已经被认为是缓慢的,初始化大量监听器可能会使情况更糟。 - luukvhoudt

9

为了完整起见,我会添加一些改动,我相信这些改动可以在性能方面有所帮助。

  1. Use delegation to bind the event to one element, instead of binding it to all existent elements.

    $(document).on({
      mouseenter: function(evt) {
        $(evt.target).data('hovering', true);
      },
      mouseleave: function(evt) {
        $(evt.target).data('hovering', false);
      }
    }, "*");
    
  2. Add a jQuery pseudo-expression :hovering.

    jQuery.expr[":"].hovering = function(elem) {
      return $(elem).data('hovering') ? true : false; 
    };
    

使用方法:

var isHovering = $('#someDiv').is(":hovering");

3

最简单的方法可能是始终跟踪鼠标悬停在哪个元素上。尝试以下代码:

<div id="1" style="border:solid 1px red; width:50px; height:50px;"></div>
<div id="2" style="border:solid 1px blue; width:50px; height:50px;"></div>
<div id="3" style="border:solid 1px green; width:50px; height:50px;"></div>

<input type="hidden" id="mouseTracker" />

​$(document).ready(function() {
    $('*').hover(function() { 
        $('#mouseTracker').val(this.id);
    });
});

然后你的函数就是这样的
function mouseIsOverElement(elemId) {
    return elemId === $('#mouseTracker').val();
}

2

你不能只检查 $(select).is(':hover') 吗?


5
下投票可以节省时间,因为使用jQuery 1.8及更高版本,这个解决方案不再可行。 jQuery 1.8已经弃用了.is(':hover'): https://dev59.com/kWfWa4cB1Zd3GeqPgV-Y#12517725。 - avernet

1
我使用自定义函数完成了这个操作:
$(document).mouseup(function(e) { 
     if(UnderElement("#myelement",e)) {
         alert("click inside element");
     }
});

function UnderElement(elem,e) {
     var elemWidth = $(elem).width();
     var elemHeight = $(elem).height();
     var elemPosition = $(elem).offset();
     var elemPosition2 = new Object;
     elemPosition2.top = elemPosition.top + elemHeight;
     elemPosition2.left = elemPosition.left + elemWidth;

     return ((e.pageX > elemPosition.left && e.pageX < elemPosition2.left) && (e.pageY > elemPosition.top && e.pageY < elemPosition2.top))
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接