我想知道如何在JavaScript中获取img和div等HTML元素的X和Y位置。


当前回答

我想我也会把这个扔出去。我还不能在旧版浏览器中测试它,但它在前3名中的最新版本中运行。:)

Element.prototype.getOffsetTop = function() {
    return ( this.parentElement )? this.offsetTop + this.parentElement.getOffsetTop(): this.offsetTop;
};
Element.prototype.getOffsetLeft = function() {
    return ( this.parentElement )? this.offsetLeft + this.parentElement.getOffsetLeft(): this.offsetLeft;
};
Element.prototype.getOffset = function() {
    return {'left':this.getOffsetLeft(),'top':this.getOffsetTop()};
};

其他回答

我接受了@meouw的回答,添加到允许边界的clientLeft中,然后创建了三个版本:

getAbsoluteOffsetFromBody-类似于@meouw,它获取相对于文档的body或html元素的绝对位置(取决于quicks模式)

getAbsoluteOffsetFromGivenElement-返回相对于给定元素的绝对位置(relativeEl)。注意,给定的元素必须包含元素el,否则其行为将与getAbsoluteOffsetFromBody相同。如果在另一个(已知)元素中包含两个元素(可选地,节点树上的多个节点),并且希望使它们处于相同的位置,则这非常有用。

getAbsoluteOffsetFromRelative-返回相对于具有position:relative的第一个父元素的绝对位置。这与getAbsoluteOffsetFromGivenElement类似,原因相同,但仅限于第一个匹配元素。

getAbsoluteOffsetFromBody = function( el )
{   // finds the offset of el from the body or html element
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromGivenElement = function( el, relativeEl )
{   // finds the offset of el from relativeEl
    var _x = 0;
    var _y = 0;
    while( el && el != relativeEl && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromRelative = function( el )
{   // finds the offset of el from the first parent with position: relative
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
        if (el != null)
        {
            if (getComputedStyle !== 'undefined')
                valString = getComputedStyle(el, null).getPropertyValue('position');
            else
                valString = el.currentStyle['position'];
            if (valString === "relative")
                el = null;
        }
    }
    return { top: _y, left: _x };
}

如果您仍然有问题,特别是与滚动有关的问题,您可以尝试查看http://www.greywyvern.com/?post=331-我注意到getStyle中至少有一段有问题的代码,假设浏览器运行正常,这段代码应该是不错的,但根本没有测试其他代码。

为了获得元素的精确偏移量,库会进行一定的长度。这里有一个简单的函数,它在我尝试过的所有情况下都能完成任务。

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; 

更新:

递归方法(在我以前的答案中)创建了许多调用堆栈。在这种情况下,我们可以使用while循环来避免递归:

/**
 *
 * @param {HTMLElement} el
 * @return {{top: number, left: number}}
 */
function getDocumentOffsetPosition(el) {
    let top = 0, left = 0;
    while (el !== null) {
        top += el.offsetTop;
        left += el.offsetLeft;
        el = el.offsetParent;
    }
    return {top, left};
}

旧答案:

/**
 *
 * @param {HTMLElement} el
 * @return {{top: number, left: number}}
 */
function getDocumentOffsetPosition(el) {
    var position = {
        top: el.offsetTop,
        left: el.offsetLeft
    };
    if (el.offsetParent) {
        var parentPosition = getDocumentOffsetPosition(el.offsetParent);
        position.top += parentPosition.top;
        position.left += parentPosition.left;
    }
    return position;
}

感谢Thinkingtiff的回答,这只是另一个版本。

使用JavaScript框架可能会更好地为您服务,该框架具有以独立于浏览器的方式返回此类信息(以及更多信息!)的功能。以下是一些:

原型jQuery框架YUI(雅虎)

使用这些框架,您可以执行以下操作:$('id-of-img').top以获得图像的y像素坐标。

jQuery.offset()将获取第一个元素的当前坐标,或者设置匹配元素集合中每个元素相对于文档的坐标。