JavaScript - elementFromPoint() method

revision:


Category : document

The elementFromPoint() method, available on the Document object, returns the topmost Element at the specified coordinates (relative to the viewport).

If the element at the specified point belongs to another document (for example, the document of an <iframe>), that document's parent element is returned (the <iframe> itself). If the element at the given point is anonymous or XBL generated content, such as a textbox's scroll bars, then the first non-anonymous ancestor element (for example, the textbox) is returned.

Elements with pointer-events set to none will be ignored, and the element below it will be returned.

If the method is run on another document (like an <iframe>'s subdocument), the coordinates are relative to the document where the method is being called.

If the specified point is outside the visible bounds of the document or either coordinate is negative, the result is null.

If you need to find the specific position inside the element, use Document.caretPositionFromPoint().

Syntax :

        elementFromPoint(x, y)
    

Parameters:

x : the horizontal coordinate of a point, relative to the left edge of the current viewport.

y : the vertical coordinate of a point, relative to the top edge of the current viewport.

Examples:

            <div>
                <p id="para1">Some text here</p>
                <button onclick="changeColor('blue');">Blue</button>
                <button onclick="changeColor('red');">Red</button>
            </div>
            <script>
                function changeColor(newColor) {
                    elem = document.elementFromPoint(2, 2);
                    elem.style.color = newColor;
                }
                               
            </script>
        

Practical examples

example: find topmost elements relative to the viewport.
code:
                    <div>
                
                    </div>
                    <script>
                        document.addEventListener('DOMContentLoaded', (loadEvent) => {
                            const pointer = document.createElement('div');
                            pointer.setAttribute('style', 'display: inline-block; position: fixed; top: -90vw; border: 0.1vw solid #ccc; 
                            border-radius: 0.4vw; padding: 1vw; background: #fff; opacity: .7;');
                            document.body.appendChild(pointer);
                    
                        let previousElement;
                        const getQuerySelector = (elem) => {
                            const tagName = elem.tagName.toLowerCase();
                            let querySelector = tagName;
                            if(elem.id.trim()) {
                                querySelector += '#' + elem.id.trim();
                            }
                            if(elem.className.trim()) {
                                querySelector += '.' + Array.apply(null, elem.classList).join('.');
                            }
                            return querySelector;
                        };
                        
                        const getElementFromPoint = (event) => {
                            pointer.style.top = (event.y + 10) + 'px';
                            pointer.style.left = (event.x + 5) + 'px';
                            const elementFromPoint = document.elementFromPoint(event.x, event.y);
                            if(!elementFromPoint || elementFromPoint === previousElement) {
                                return;
                            }
                            previousElement = elementFromPoint;
                            let parentElement = elementFromPoint;
                            let tagName = elementFromPoint.tagName.toLowerCase();
                            let querySelector = getQuerySelector(elementFromPoint);
                            while(tagName !== 'html') {
                                parentElement = parentElement.parentElement;
                                tagName = parentElement.tagName.toLowerCase();
                                querySelector = getQuerySelector(parentElement) + ' > ' + querySelector;
                            }
                            pointer.textContent = querySelector;
                        }
                        document.addEventListener('mousemove', getElementFromPoint); 
                        document.addEventListener('click'    , getElementFromPoint); 
                        });
                                        
                    </script>