160

I want a function that tells me which element the mouse cursor is over.

So, for example, if the user's mouse is over this textarea (with id wmd-input), calling window.which_element_is_the_mouse_on() will be functionally equivalent to $("#wmd-input").

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tom Lehman
  • 85,973
  • 71
  • 200
  • 272

14 Answers14

209

DEMO

There's a really cool function called document.elementFromPoint which does what it sounds like.

What we need is to find the x and y coords of the mouse and then call it using those values:

document.addEventListener('mousemove', e => {
  console.clear()
  console.log( document.elementFromPoint(e.clientX, e.clientY) )
}, {passive: true})
[class^='level']{
  width: 100px;
  height: 100px;
  padding: 15px;
  background: #00000033;
}
<div class='level-1'>
  <div class='level-2'>
    <div class='level-3'>
      Hover
    </div>
  </div>
</div>

document.elementFromPoint

jQuery event object

vsync
  • 118,978
  • 58
  • 307
  • 400
qwertymk
  • 34,200
  • 28
  • 121
  • 184
  • This was what I thought of too, but I didn't know about `elementFromPoint` (and didn't bother looking :)). It's a cool function. Is it supported by all the major browsers? – Tikhon Jelvis Jan 11 '12 at 01:52
  • 1
    @TikhonJelvis: Well from [here](http://stackoverflow.com/questions/1259585/get-element-at-specified-position-javascript) I see it's supported on IE and firefox. If you get those two you usually get them all. [MSDN](http://msdn.microsoft.com/en-us/library/ms536417%28VS.85%29.aspx) [MDN](https://developer.mozilla.org/en/DOM/document.elementFromPoint) – qwertymk Jan 11 '12 at 02:00
  • Awesome. It also works on Chrome (at least 16 on Linux). And I don't really care about Safari, but it probably works there too. – Tikhon Jelvis Jan 11 '12 at 02:02
  • 4
    Awesome. Is there any way to get the coords of the mouse WITHOUT catching an event? (Probably not I assume). If this isn't possible, then unfortunately I don't think this method is any better than `event.target` or whatever – Tom Lehman Jan 11 '12 at 18:08
  • 1
    @HoraceLoeb It's not possible to get the mouse coords without catching an event. see [this SO question](http://stackoverflow.com/questions/1133807/determine-mouse-position-outside-of-events-using-jquery) for further explanation – Logan Besecker Dec 16 '12 at 22:54
  • @HoraceLoeb It is possible using jQuery `$(':hover')`. Demo : http://jsfiddle.net/pmrotule/2pks4tf6/ – pmrotule Mar 04 '15 at 22:47
  • 2
    That's a weird way to do it. If you catch an event, why not just using `event.target` ? – pmrotule Mar 04 '15 at 23:01
  • 3
    Answer does not explain what `event` is, and how it came to be – vsync May 14 '17 at 13:49
  • 1
    This is in mousemove event. And you can't use event.target because that's undefined if the mouse isn't pressed. Even if the mouse is pressed, event.target stays as the element that the click started on. – Curtis Jun 27 '20 at 04:50
87

In newer browsers, you could do the following:

document.querySelectorAll( ":hover" );

That'll give you a NodeList of items that the mouse is currently over in document order. The last element in the NodeList is the most specific, each preceding one should be a parent, grandparent, and so on.

dherman
  • 2,832
  • 20
  • 23
  • 2
    I created a fiddle with `$(':hover')` but it's basically the same thing: http://jsfiddle.net/pmrotule/2pks4tf6/ – pmrotule Mar 04 '15 at 22:52
  • 4
    `(function(){ var q = document.querySelectorAll(":hover"); return q[q.length-1]; })()` – user Apr 06 '16 at 01:59
  • You'd be amazed at how many DOM traversals your computer can do while it waits for the incredibly slow human to move the mouse another pixel. – Rick Mohr Mar 01 '22 at 13:56