Skip to content

Instantly share code, notes, and snippets.

@oslego
Created November 1, 2013 13:25
Show Gist options
  • Save oslego/7265412 to your computer and use it in GitHub Desktop.
Save oslego/7265412 to your computer and use it in GitHub Desktop.
//
// returns a list of all elements under the cursor
//
function elementsFromPoint(x,y) {
var elements = [], previousPointerEvents = [], current, i, d;
// get all elements via elementFromPoint, and remove them from hit-testing in order
while ((current = document.elementFromPoint(x,y)) && elements.indexOf(current)===-1 && current != null) {
// push the element and its current style
elements.push(current);
previousPointerEvents.push({
value: current.style.getPropertyValue('pointer-events'),
priority: current.style.getPropertyPriority('pointer-events')
});
// add "pointer-events: none", to get to the underlying element
current.style.setProperty('pointer-events', 'none', 'important');
}
// restore the previous pointer-events values
for(i = previousPointerEvents.length; d=previousPointerEvents[--i]; ) {
elements[i].style.setProperty('pointer-events', d.value?d.value:'', d.priority);
}
// return our results
return elements;
}
@luiz-brandao
Copy link

This works beautifully! Thanks!

@pravin-d
Copy link

Dude pointer-events are not supported by old browers especially IE 10 and so.. Any Idea how to get it done on IE 10 or older ?
Though seems to be a good polyfill for elementsfrompoint()
http://caniuse.com/#feat=pointer-events
https://developer.mozilla.org/en/docs/Web/CSS/pointer-events#Browser_compatibility

@Jip-Hop
Copy link

Jip-Hop commented Feb 26, 2016

Nice way of emulating document.elementsFromPoint()
I'm not sure if you're aware of this, but pointer-events inheritance can cause issues with this approach.
In this example: https://jsbin.com/larukoxoqa/edit?html,css,js,output your approach misses the p tag with purple background, whereas document.elementsFromPoint() does find the p. Since the div is found first, pointer-events: 'none' is set and this will also affect the child p, which is positioned below the div. The result is output by console.log()

From: https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

auto
The element behaves as it would if the pointer-events property were not specified. In SVG content, this value and the value visiblePainted have the same effect.

none
The element is never the target of mouse events; however, mouse events may target its descendant elements if those descendants have pointer-events set to some other value. In these circumstances, mouse events will trigger event listeners on this parent element as appropriate on their way to/from the descendant during the event capture/bubble phases.

It seems the solution is to explicitly set pointer-events: 'auto' on all elements on the page, so they won't inherit from their parents. With a css rule * { pointer-events:auto} the p tag is not missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment