admin管理员组文章数量:1129645
I'm not looking for an action to call when hovering, but instead a way to tell if an element is being hovered over currently. For instance:
$('#elem').mouseIsOver(); // returns true or false
Is there a jQuery method that accomplishes this?
I'm not looking for an action to call when hovering, but instead a way to tell if an element is being hovered over currently. For instance:
$('#elem').mouseIsOver(); // returns true or false
Is there a jQuery method that accomplishes this?
Share Improve this question asked Jan 24, 2012 at 2:51 James SkidmoreJames Skidmore 50.3k33 gold badges110 silver badges137 bronze badges 2- Just in case someone is looking for other solutions stackoverflow.com/questions/1273566/… – Jo E. Commented Jan 2, 2014 at 7:06
- 1 The marking as duplicate looks quite wrong. The question does not say what the intent is, for someone else to read the mind of the OP and decide it's a collision detection question and mark as duplicate. – Meligy Commented Apr 27, 2016 at 1:18
12 Answers
Reset to default 322Original (And Correct) Answer:
You can use is()
and check for the selector :hover
.
var isHovered = $('#elem').is(":hover"); // returns true or false
Example: http://jsfiddle.net/Meligy/2kyaJ/3/
(This only works when the selector matches ONE element max. See Edit 3 for more)
.
Edit 1 (June 29, 2013): (Applicable to jQuery 1.9.x only, as it works with 1.10+, see next Edit 2)
This answer was the best solution at the time the question was answered. This ':hover' selector was removed with the .hover()
method removal in jQuery 1.9.x.
Interestingly a recent answer by "allicarn" shows it's possible to use :hover
as CSS selector (vs. Sizzle) when you prefix it with a selector $($(this).selector + ":hover").length > 0
, and it seems to work!
Also, hoverIntent plugin mentioned in a another answer looks very nice as well.
Edit 2 (September 21, 2013): .is(":hover")
works
Based on another comment I have noticed that the original way I posted, .is(":hover")
, actually still works in jQuery, so.
It worked in jQuery 1.7.x.
It stopped working in 1.9.1, when someone reported it to me, and we all thought it was related to jQuery removing the
hover
alias for event handling in that version.It worked again in jQuery 1.10.1 and 2.0.2 (maybe 2.0.x), which suggests that the failure in 1.9.x was a bug or so not an intentional behaviour as we thought in the previous point.
If you want to test this in a particular jQuery version, just open the JSFidlle example at the beginning of this answer, change to the desired jQuery version and click "Run". If the colour changes on hover, it works.
.
Edit 3 (March 9, 2014): It only works when the jQuery sequence contains a single element
As shown by @Wilmer in the comments, he has a fiddle which doesn't even work against jQuery versions I and others here tested it against. When I tried to find what's special about his case I noticed that he was trying to check multiple elements at a time. This was throwing Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: hover
.
So, working with his fiddle, this does NOT work:
var isHovered = !!$('#up, #down').filter(":hover").length;
While this DOES work:
var isHovered = !!$('#up,#down').
filter(function() { return $(this).is(":hover"); }).length;
It also works with jQuery sequences that contain a single element, like if the original selector matched only one element, or if you called .first()
on the results, etc.
This is also referenced at my JavaScript + Web Dev Tips & Resources Newsletter.
Use:
var hovered = $("#parent").find("#element:hover").length;
jQuery 1.9+
It does not work in jQuery 1.9. Made this plugin based on user2444818's answer.
jQuery.fn.mouseIsOver = function () {
return $(this).parent().find($(this).selector + ":hover").length > 0;
};
http://jsfiddle.net/Wp2v4/1/
The accepted answer didn't work for me on JQuery 2.x
.is(":hover")
returns false on every call.
I ended up with a pretty simple solution that works:
function isHovered(selector) {
return $(selector+":hover").length > 0
}
Set a flag on hover:
var over = false;
$('#elem').hover(function() {
over = true;
},
function () {
over = false;
});
Then just check your flag.
Couple updates to add after working on this subject for a while:
- all solutions with .is(":hover") break on jQuery 1.9.1
- The most likely reason to check if the mouse is still over an element is to attempt to prevent events firing over each other. For example, we were having issues with our mouseleave being triggered and completed before our mouseenter event even completed. Of course this was because of a quick mouse movement.
We used hoverIntent https://github.com/briancherne/jquery-hoverIntent to solve the issue for us. Essentially it triggers if the mouse movement is more deliberate. (one thing to note is that it will trigger on both mouse entering an element and leaving - if you only want to use one pass the constructor an empty function )
You can filter your elment from all hovered elements. Problematic code:
element.filter(':hover')
Save code:
jQuery(':hover').filter(element)
To return boolean:
jQuery(':hover').filter(element).length===0
Expanding on @Mohamed's answer. You could use a little encapsulation
Like this:
jQuery.fn.mouseIsOver = function () {
if($(this[0]).is(":hover"))
{
return true;
}
return false;
};
Use it like:
$("#elem").mouseIsOver();//returns true or false
Forked the fiddle: http://jsfiddle.net/cgWdF/1/
I like the first response, but for me it's weird. When attempting to check just after page load for the mouse, I have to put in at least a 500 millisecond delay for it to work:
$(window).on('load', function() {
setTimeout(function() {
$('img:hover').fadeOut().fadeIn();
}, 500);
});
http://codepen.io/molokoloco/pen/Grvkx/
https://api.jquery.com/hover/
Asynchronous function in line 38:
$( ".class#id" ).hover(function() {
Your javascript
});
Setting a flag per kinakuta's answer seems reasonable, you can put a listener on the body so you can check if any element is being hovered over at a particular instant.
However, how do you want to deal with child nodes? You should perhaps check if the element is an ancestor of the currently hovered element.
<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>
There're so many ways this can be achieved. I personally don't like styling elements directly, I'd rather add the style from css, makes things easier when trying to override or change them.
<style type="text/css">.red-bg { background: red; }</style>
$('#my_element').hover(function() {
$(this).parent().toggleClass('red-bg');
});
OR
$('#my_element').hover(function() {
$(this).parent().addClass('red-bg');
}, function() {
$(this).parent().removeClass('red-bg');
});
OR using mouse enter and mouse leave
$(document).on('mouseenter', '#my_element', function() {
$(this).parent().addClass('red-bg');
});
$(document).on('mouseenter', '#my_element', function() {
$(this).parent().removeClass('red-bg');
});
本文标签: javascriptDetect IF hovering over element with jQueryStack Overflow
版权声明:本文标题:javascript - Detect IF hovering over element with jQuery - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736750389a1951004.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论