Retrieve the position (X,Y) of an HTML element relative to the browser window

前端 未结 27 3782
闹比i
闹比i 2020-11-21 04:59

I want to know how to get the X and Y position of HTML elements such as img and div in JavaScript relative to the browser window.

相关标签:
27条回答
  • 2020-11-21 05:35

    I did it like this so it was cross-compatible with old browsers.

    // For really old browser's or incompatible ones
        function getOffsetSum(elem) {
            var top = 0,
                left = 0,
                bottom = 0,
                right = 0
    
             var width = elem.offsetWidth;
             var height = elem.offsetHeight;
    
            while (elem) {
                top += elem.offsetTop;
                left += elem.offsetLeft;
                elem = elem.offsetParent;
            }
    
             right = left + width;
             bottom = top + height;
    
            return {
                top: top,
                left: left,
                bottom: bottom,
                right: right,
            }
        }
    
        function getOffsetRect(elem) {
            var box = elem.getBoundingClientRect();
    
            var body = document.body;
            var docElem = document.documentElement;
    
            var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
            var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
    
            var clientTop = docElem.clientTop;
            var clientLeft = docElem.clientLeft;
    
    
            var top = box.top + scrollTop - clientTop;
            var left = box.left + scrollLeft - clientLeft;
            var bottom = top + (box.bottom - box.top);
            var right = left + (box.right - box.left);
    
            return {
                top: Math.round(top),
                left: Math.round(left),
                bottom: Math.round(bottom),
                right: Math.round(right),
            }
        }
    
        function getOffset(elem) {
            if (elem) {
                if (elem.getBoundingClientRect) {
                    return getOffsetRect(elem);
                } else { // old browser
                    return getOffsetSum(elem);
                }
            } else
                return null;
        }
    

    More about coordinates in JavaScript here: http://javascript.info/tutorial/coordinates

    0 讨论(0)
  • 2020-11-21 05:36

    After much research and testing this seems to work

    function getPosition(e) {
        var isNotFirefox = (navigator.userAgent.toLowerCase().indexOf('firefox') == -1);
        var x = 0, y = 0;
        while (e) {
            x += e.offsetLeft - e.scrollLeft + (isNotFirefox ? e.clientLeft : 0);
            y += e.offsetTop - e.scrollTop + (isNotFirefox ? e.clientTop : 0);
            e = e.offsetParent;
        }
        return { x: x + window.scrollX, y: y + window.scrollY };
    }
    

    see http://jsbin.com/xuvovalifo/edit?html,js,output

    0 讨论(0)
  • 2020-11-21 05:37

    This is the best code I've managed to create (works in iframes as well, unlike jQuery's offset()). Seems webkit has a bit of a different behavior.

    Based on meouw's comment:

    function getOffset( el ) {
        var _x = 0;
        var _y = 0;
        while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
            _x += el.offsetLeft - el.scrollLeft;
            _y += el.offsetTop - el.scrollTop;
            // chrome/safari
            if ($.browser.webkit) {
                el = el.parentNode;
            } else {
                // firefox/IE
                el = el.offsetParent;
            }
        }
        return { top: _y, left: _x };
    }
    
    0 讨论(0)
  • 2020-11-21 05:39

    The correct approach is to use element.getBoundingClientRect():

    var rect = element.getBoundingClientRect();
    console.log(rect.top, rect.right, rect.bottom, rect.left);
    

    Internet Explorer has supported this since as long as you are likely to care about and it was finally standardized in CSSOM Views. All other browsers adopted it a long time ago.

    Some browsers also return height and width properties, though this is non-standard. If you're worried about older browser compatibility, check this answer's revisions for an optimised degrading implementation.

    The values returned by element.getBoundingClientRect() are relative to the viewport. If you need it relative to another element, simply subtract one rectangle from the other:

    var bodyRect = document.body.getBoundingClientRect(),
        elemRect = element.getBoundingClientRect(),
        offset   = elemRect.top - bodyRect.top;
    
    alert('Element is ' + offset + ' vertical pixels from <body>');
    
    0 讨论(0)
  • 2020-11-21 05:40

    You can add two properties to Element.prototype to get the top/left of any element.

    Object.defineProperty( Element.prototype, 'documentOffsetTop', {
        get: function () { 
            return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
        }
    } );
    
    Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
        get: function () { 
            return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
        }
    } );
    

    This is called like this:

    var x = document.getElementById( 'myDiv' ).documentOffsetLeft;
    

    Here's a demo comparing the results to jQuery's offset().top and .left: http://jsfiddle.net/ThinkingStiff/3G7EZ/

    0 讨论(0)
  • 2020-11-21 05:41

    The libraries go to some lengths to get accurate offsets for an element.
    here's a simple function that does the job in every circumstances that I've tried.

    function getOffset( el ) {
        var _x = 0;
        var _y = 0;
        while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
            _x += el.offsetLeft - el.scrollLeft;
            _y += el.offsetTop - el.scrollTop;
            el = el.offsetParent;
        }
        return { top: _y, left: _x };
    }
    var x = getOffset( document.getElementById('yourElId') ).left; 
    
    0 讨论(0)
提交回复
热议问题