One can determine the element below the mouse cursor (i.e. the top-most hovered element) with the following techniques:
- Listen for the
mousemove
event. The target isevent.target
ordocument.elementFromPoint(event.clientX, event.clientY)
.
This does not work when scrolling while not moving the mouse. Then, the mouse technically doesn’t move; thus, no mouse event will fire.
Unfortunately, both techniques from above are no longer applicable when listening for the scroll
event. event.target
will be whichever element is scrolled (or document
). Also, the mouse cursor position is not exposed on the event
object.
As described in this answer to “Determine which element the mouse pointer is on top of in Javascript”, one possible solution is querying the hovered element via the CSS :hover
pseudo-class.
document.addEventListener('scroll', () => {
const hoverTarget = document.querySelector('.element:hover');
if (hoverTarget) {
hover(hoverTarget);
}
});
However, this is not usable because it is very inefficient and inaccurate. The scroll
event is one of the rapidly firing events and needs to be slowed down when performing anything mildly costly (e.g. querying the DOM).
Also, the hovered element lags behind when scrolling. You can observe this on any kind of website with a lot of links: Hover over one of them and scroll to another link without moving the mouse. It updates only after a few milliseconds.
Is there any way, this can be implemented nicely and efficient? Basically, I want the inverse of mouseenter
: Instead of knowing when the mouse enters and element, I want to know when an element intersects with the mouse (e.g. when the mouse is not moved but the element [i.e. when scrolling]).