jQuery:如何检查鼠标是否悬停在元素上

12

我有一个延迟执行的函数,它绑定了一个mouseenter事件:

$(window).load(function(e) {
  var $container = $('.container');
  $container.mouseenter(function(e) {
    //do something
  });
  ...
});
问题在于当load事件触发时,鼠标可能已经悬停在元素上,因此在绑定mouseenter事件之前。
我可以通过在页面加载处理程序的末尾放置一些代码来解决这个问题,进行一次检查以确定鼠标是否在元素内部,并手动触发mouseenter事件。
// check if the mouse is inside $container
if(mouse is inside $container)
  $container.mouseenter();

在load事件中,我如何检查鼠标是否悬停在元素上?

我尝试了$container.is(':hover'),但它不起作用。


你尝试过使用mouseenter和mouseleave事件吗? - Emmanuel N
2
$container.is(':hover') - 这种方式有什么问题吗?我的担忧是它不是特别兼容(例如在IE7中无法工作,因为它依赖于qSA行为),但在我看来它似乎可以实现你想要的功能... - lonesomeday
@lonesomeday:请访问http://jsfiddle.net/UVJgF/1/,将鼠标悬停在黑色框上并按下ctr+enter。在FF8上无法触发。 - spb
6个回答

2

我还没有测试过,但我认为你想要这样的结果...

function checkMouseCollision(obj) {
    var offset = obj.offset();
    objX= offset.left;
    objY=offset.top;
    objW=obj.width();
    objH=obj.height();

    var mouseX = 0;
    var mouseY = 0;
    $().mousemove( function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
    });

    if((mouseX>objX&&mouseX<objX+objW)&&(mouseY>objY&&mouseY<objY+objH)){
        alert("hovered")     
    };
};
checkCollision($(".box"))

这个方法可以行得通,但是mousemove事件会被频繁调用。如果可能的话,我希望有一种方法只进行一次检查 :) - spb
@spb 你考虑过在事件中使用 .one() 而不是 .on() 吗? - Cade Roux

1

1

最好的方法是获取元素的左、右、上和下偏移量,并查看鼠标位置是否在这些值之间。

示例

第一次加载时将鼠标放在 div 上。然后刷新页面(点击 F5,这样您就不必移动鼠标)。下次完全加载页面时,即使您没有移动鼠标,它也应该弹出“悬停!”的警报。

或者更简单的方法。只需检查 mousemove 事件的 e.target.id(显然即使没有移动鼠标也会触发该事件)与元素的 id 是否匹配,如下所示:

$(document).mousemove(function(e){
    if( e.target.id === 'hoverTest'){
        alert("Hovered!");
    }
});

示例(执行与上述步骤相同的操作)。


这似乎不能在FF8上解决。明确一点 - 如果我将鼠标放在块上并获取第一个悬停弹出窗口,然后按Enter键,然后按F5(或Ctrl-F5)进行刷新,即使鼠标位于框上,我也不会再次弹出另一个弹出窗口,直到我稍微移动鼠标。 - Cade Roux
在我的Chrome上运行良好 - 看起来又是一个跨浏览器的问题。你遇到了哪个浏览器产生了那个错误? - Purag
在 Cr-48 笔记本电脑上,FireFox 8.0 和 Chrome 16.0.912.59 上都会弹出警报,即使鼠标没有移动,因此很难测试。但我选择了“不再弹出”,然后移动到框上,按下 F5,直到我开始移动鼠标它才会再次弹出。 - Cade Roux
@Purmou:这个变体可能可行:在mousemove事件中,我可以检查鼠标是否悬停在元素上,并设置一个标志位true或false。然后我可以在window.load事件处理程序中检查该标志位。如果没有更简单的方法,我将采用这种方式。 - spb

1

使用 jQuery 1.7+,您将想要使用 .on()http://api.jquery.com/on/

$(document).ready(function(){
    $('body').on("mouseover", "your_element_selector_here", function() {
        // do stuff here
    });
});

.live已被弃用。您也可以将任何其他事件放在.on中,具体取决于您的需求。:hover不起作用,因为它只适用于特定元素,并且基于css。

在页面完成加载之前,结合偏移检测方法使用此方法将帮助您达到所需效果。


有趣。is .mouseenter或.mouseover也被弃用了吗?这些看起来不如.on冗长。 - spb
不,但你应该使用.on()方法。就像老的已弃用的.live()方法一样,绑定将存在,即使通过ajax重新绘制绑定元素(your_element_here)。但是有一个问题,就是它的父元素(你在其上调用'on'的元素)在页面生命周期中不能被重新绘制。因为.on()方法赋给了它,必须始终存在。 - Stone

-1

Mouseover事件正好符合您的需求。

如果在您附加mouseover事件时(未来动态添加),.container不存在,则必须使用.live方法来附加事件。

$(".conteiner").live("mouseover", function() {
   alert("hovered!");
}) 

即使鼠标已经在新元素出现的位置,它也可以正常工作。 这里有一个例子!

对于 jQuery 1.7+,您应该使用.on方法,因为.live方法已被弃用。 这里有一个例子!


我希望有一种不使用事件检查的方法。 - spb
4
如果鼠标在页面加载时已经悬停在一个元素上,那么 mouseover 事件将不会触发。这就是问题的要点。 - James Allardice
你确定 mouseover 事件不会触发吗? - Petr Peller

-2
$('.container').mouseover(function(e) {
    //do something
});

我需要先等待页面加载,但这时鼠标可能已经移到元素上了。 - spb

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