使用jQuery检测IF悬停在元素上


149

我不是在寻找一个行动调用的时候徘徊,而是要告诉的方式,如果一个元素正在上空盘旋目前。例如:

$('#elem').mouseIsOver(); // returns true or false

是否有实现此目标的jQuery方法?


万一有人找其他的解决方案stackoverflow.com/questions/1273566/...
乔E.

1
标记为重复的标记看起来非常错误。问题没有说明意图是什么,对于其他人来说,阅读OP的思想并确定这是一个冲突检测问题并将其标记为重复。
Meligy

Answers:


305

原始(正确)答案:

您可以使用is()并检查选择器:hover

var isHovered = $('#elem').is(":hover"); // returns true or false

示例:http//jsfiddle.net/Meligy/2kyaJ/3/

(这仅在选择器最多匹配一个元素时有效。有关更多信息,请参见“编辑3”。)

编辑1(2013年6月29日):(仅适用于jQuery 1.9.x,因为它与1.10+兼容,请参阅下一个编辑2)

在回答问题时,此答案是最好的解决方案。这个':hover'选择器.hover()在jQuery 1.9.x中被删除了。

有趣的是,“ allicarn”最近的回答显示,:hover当您为选择器添加前缀时,可以将其用作CSS选择器(与Sizzle相对)$($(this).selector + ":hover").length > 0

另外,另一个答案中提到的hoverIntent插件看起来也很好。

编辑2(2013年9月21日): .is(":hover") 作品

根据另一条评论,我注意到我发布的原始方式.is(":hover")实际上仍然可以在jQuery中使用,因此。

  1. 它在jQuery 1.7.x中有效。

  2. 当有人向我报告它时,它在1.9.1中停止工作,我们都认为它与jQuery删除该hover版本中事件处理的别名有关。

  3. 它在jQuery 1.10.1和2.0.2(也许是2.0.x)中再次起作用,这表明1.9.x中的失败是一个错误,或者不是我们先前所想的故意行为。

如果要在特定的jQuery版本中进行测试,只需在此答案的开头打开JSFidlle示例,更改为所需的jQuery版本,然后单击“运行”。如果颜色在悬停时发生变化,则可以使用。

编辑3(2014年3月9日):仅当jQuery序列包含单个元素时,此功能才有效

如@Wilmer在评论中所示,他有一个小提琴,甚至无法针对我和其他人对其进行测试的jQuery版本进行测试。当我尝试查找有关他的案子的特殊之处时,我注意到他正在尝试一次检查多个要素。这是投掷的Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: hover

所以,他的小提琴的工作,但这工作:

var isHovered = !!$('#up, #down').filter(":hover").length;

虽然这DOES工作:

var isHovered = !!$('#up,#down').
                    filter(function() { return $(this).is(":hover"); }).length;

它也适用于包含单个元素的jQuery序列,例如原始选择器仅匹配一个元素,或者您调用.first()了结果等。

我的JavaScript + Web开发技巧和资源时事通讯也对此进行了引用。


1
效果很好,很简单。谢谢穆罕默德!
James Skidmore 2012年

18
在IE 8中引发错误:Syntax Error, unrecognized expression: hover. jquery-1.7.js line 4179
RobG 2012年

确实如此。刚刚测试。对于IE6,请尝试使用此处描述的hack,方法是peterned.home.xs4all.nl/csshover.html,否则请回到正常的悬停状态下添加一些状态,然后清除以后的解决方案。
Meligy 2012年

1
@Meligy:我已经分叉了您的小提琴,以说明它不能与所选内容中的多个项目一起使用:jsfiddle.net/p34n8
SuperNova

1
另外,如果您使用的是jQuery mobile,那么也要拧紧它-检查基甸答案中的小提琴,然后打开jQuery Mobile 1.4.4框,然后您会看到它不起作用... 1.4.2以及:(
David O'Sullivan 2014年


9

它在jQuery 1.9中不起作用。根据user2444818的答案制作了此插件。

jQuery.fn.mouseIsOver = function () {
    return $(this).parent().find($(this).selector + ":hover").length > 0;
}; 

http://jsfiddle.net/Wp2v4/1/


5

在悬停时设置标志:

var over = false;
$('#elem').hover(function() {
  over = true;
},
function () {
  over = false;
});

然后只需检查您的标志即可。


简单,但不容易重用。:/
Trevor 2012年

似乎在我的特定情况下不起作用,但是我同意这是一个很好的选择。就我而言,当我mouseleave一个元素时,我想检查一下鼠标是否进入了另一个特定元素。
James Skidmore 2012年

@JamesSkidmore-在mouseleave事件中,您可以使用e.fromElemente.toElement。那对你有用吗?
mrtsherman 2012年

您可以对其进行更新,以使用覆盖所有适用元素的选择器,然后使用将该标志存储在各个元素上.data()
nnnnnn 2012年

@Trevor-true-您需要将状态存储在元素上,然后创建一个检查(大概是数据标签)状态的函数。
kinakuta 2012年

4

经过一段时间的研究后,夫妇进行了更新以添加:

  1. 所有带有.is(“:hover”)的解决方案都在jQuery 1.9.1上中断
  2. 检查鼠标是否仍在元素上方的最可能原因是试图防止事件相互触发。例如,我们在mouseenter事件甚至尚未完成之前就触发并完成mouseleave时遇到了问题。当然,这是由于鼠标快速移动。

我们使用了hoverIntent https://github.com/briancherne/jquery-hoverIntent为我们解决了这个问题。本质上,它会触发鼠标移动是否更加刻意。(要注意的是,它将在鼠标进入元素并离开时触发—如果您只想使用一次构造函数的空函数)


4

您可以从所有悬停的元素中过滤元素。有问题的代码:

element.filter(':hover')

保存代码:

jQuery(':hover').filter(element)

要返回布尔值:

jQuery(':hover').filter(element).length===0

4

在JQuery 2.x上,接受的答案对我不起作用, .is(":hover")每次调用都返回false。

我最终得到了一个非常简单的解决方案,该解决方案有效:

function isHovered(selector) {

    return $(selector+":hover").length > 0

}

3

扩展@Mohamed的答案。您可以使用一些封装

像这样:

jQuery.fn.mouseIsOver = function () {
    if($(this[0]).is(":hover"))
    {
        return true;
    }
    return false;
}; 

像这样使用它:

$("#elem").mouseIsOver();//returns true or false

分叉的小提琴:http : //jsfiddle.net/cgWdF/1/


6
为此,您也可以这样做:jQuery.fn.mouseIsOver = function(){return $(this [0])。is(':hover')}; 更少的代码
Lathan 2012年

32
简单地执行$('#elem')。is(':hover')
有多困难

这不是艰苦的事情,而是更明确地表达了意图。但是对每个人来说都是自己的。
基甸,

1

我喜欢第一反应,但对我来说很奇怪。尝试在页面加载后立即检查鼠标时,我必须至少延迟500毫秒才能使其正常工作:

$(window).on('load', function() {
    setTimeout(function() {
        $('img:hover').fadeOut().fadeIn();
    }, 500);
});

http://codepen.io/molokoloco/pen/Grvkx/


0

为kinakuta的答案设置一个标志似乎是合理的,您可以在身上放置一个侦听器,以便可以检查在特定时刻是否悬停了任何元素。

但是,您如何处理子节点?您也许应该检查该元素是否是当前悬停元素的祖先。

<script>

var isOver = (function() {
  var overElement;
  return {

    // Set the "over" element
    set: function(e) {
      overElement = e.target || e.srcElement;
    },

    // Return the current "over" element
    get: function() {
      return overElement;    
    },

    // Check if element is the current "over" element
    check: function(element) {
      return element == overElement;
    },

    // Check if element is, or an ancestor of, the 
    // current "over" element
    checkAll: function(element) {
      while (overElement.parentNode) {
         if (element == overElement) return true;
         overElement = overElement.parentNode;
      }
      return false;
    }
  };
}());


// Check every second if p0 is being hovered over
window.setInterval( function() {
  var el = document.getElementById('p0');
  document.getElementById('msg').innerHTML = isOver.checkAll(el);
}, 1000);


</script>

<body onmouseover="isOver.set(event);">
  <div>Here is a div
    <p id="p0">Here is a p in the div<span> here is a span in the p</span> foo bar </p>
  </div>
  <div id="msg"></div>
</body>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.