7

WRT building a Firefox Add-on.

Is it possible to get the element under the mouse via some XPCOM or javascript method? (non-js-ctypes please as that requires OS specificity)

I want to detect what is under the mouse when user presses Ctrl + Shift + M.

Right now I'm adding a mouseover listener to the document when the user presses this hotkey, so I can get the element under the mouse when he moves it, but not the element that was under the mouse exactly when he pressed the hotkey combination.

Noitidart
  • 35,443
  • 37
  • 154
  • 323
Blagoh
  • 1,225
  • 1
  • 14
  • 29
  • i would suggest having a listener on the `mousemove` event to track the mouse. then using the mouse's coordinates, find the element beneath it. this is annoying but possible. see more here: http://stackoverflow.com/questions/7790725/javascript-track-mouse-position – user428517 Jul 02 '14 at 18:30
  • The issue with `elementFromPoint` is I have to add `mousemove` and the element will not be available until user makes movement of mouse after pressing hotkey. I basically use the 2nd method in this solution: http://stackoverflow.com/a/4711224/3791822 – Blagoh Jul 02 '14 at 18:34
  • 1
    listen on `mousemove` ALL the time, storing the position somewhere. then when the key combination is pressed, use the last recorded mouse position. – user428517 Jul 02 '14 at 18:36
  • Oh yes that's an idea, I had that too but forgot to mention it so up vote for that. A persistent `mousemove` is not so good for performance especially from the add-on scope so I was hoping to avoid that please. – Blagoh Jul 02 '14 at 18:43
  • then you're probably out of luck. are you sure it hurts performance that much? i've done things like this before with little issue. a simple handler that updates xy values in an array is not very taxing. that's all it would need to do. – user428517 Jul 02 '14 at 18:47
  • The add-on approval comitte warn against it. I can use it, but they prefer I find some alternative. They don't mind if I added the mousemove when the hotkey is pressed and remove it when user releases the hotkey, but elements in my add-on are zoomed real big, so pixel level, so a single pixel will select something else. :( – Blagoh Jul 02 '14 at 19:03
  • i can't think of another way to do this, then (at least using js) – user428517 Jul 02 '14 at 19:03

1 Answers1

14

I just looked through the source for code that gets (or stores and makes available) the cursor position. I didn't find anything one could use (from Javascript, XPCOM or not). I might have missed something... MXR is your friend.

However, if you want to avoid mousemove (and this is a good idea in general), you can just look for the innermost hovered element, e.g. like so.

function getInnermostHovered() {
    var n = document.querySelector(":hover");
    var nn;
    while (n) {
        nn = n;
        n = nn.querySelector(":hover");
    }
    return nn;
}

(fiddle demoing the principle)

While this is what I'd consider a hack, it seems to work good enough most of the time, but will fail if the element has mouse events disabled via pointer-events. There could be other issues I didn't think of...

Of course, this can return nothing when the document has no hovered element (e.g. the mouse is not actually within the document).

nmaier
  • 32,336
  • 5
  • 63
  • 78
  • 2
    This is indeed a clever idea - I believe it can be simplified however using querySelectorAll as it's order should always be such that the element you want is at the end. i.e. `function getInnermostHovered() { return [].slice.call(document.querySelectorAll(':hover')).pop(); }` – MDEV Aug 31 '17 at 14:31
  • Interesting idea @SmokeyPHP – nmaier Aug 31 '17 at 15:28
  • 2
    Indeed, `Array.from(document.querySelectorAll(":hover")).pop()` would work, however for very large documents, depending on browser engine, I could imagine it will walk the entire tree looking for `:hover` while the recursive `.querySelector` would prune subtrees early on. Or maybe browsers that matter have it optimized enough... Needs some performance testing. – nmaier Aug 31 '17 at 15:36
  • Good point, it's brevity may not be worth the possible performance hit for certain document sizes/browsers. I've just run a few tests and it does indeed seem to be faster (in the latest FF & Chrome at least) to 'manually' walk the more specific tree - sometimes a negligible difference, but a difference nonetheless – MDEV Sep 04 '17 at 13:51
  • For anyone looking now, MXR appears to have been replaced by [SearchFox](https://searchfox.org/). – Polynomial Apr 08 '21 at 15:48