当前位置:  开发笔记 > 编程语言 > 正文

检索HTML元素的位置(X,Y)

如何解决《检索HTML元素的位置(X,Y)》经验,为你挑选了18个好方法。

我想知道如何获得HTML元素的X和Y位置,例如imgdivJavaScript.



1> Andy E..:

正确的方法是使用element.getBoundingClientRect():

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

Internet Explorer已经支持这个,因为只要你可能关心它,它最终在CSSOM Views中被标准化.所有其他浏览器很久以前就采用了它.

某些浏览器还返回高度和宽度属性,但这不是标准的.如果您担心较旧的浏览器兼容性,请查看此答案的修订版,以获得优化的降级实现.

返回的值element.getBoundingClientRect()相对于视口.如果您需要它相对于另一个元素,只需从另一个元素中减去一个矩形:

var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;

alert('Element is ' + offset + ' vertical pixels from ');


一篇[关于JS坐标的非常有趣的文章](http://javascript.info/tutorial/coordinates).这篇文章在SO上没有提到,应该......
不起作用......它是垂直和水平的8像素,因为身体的8px边距.Meouw的解决方案完美无缺.如果你想我有一个小测试来证明这个问题.
@CpnCrunch:我明白你的意思了; 我没有意识到你指的是我答案的后半部分.当主体具有边缘时,其边界框将偏移每个相应侧的像素数.在这种情况下,您还必须从身体坐标中减去计算的边距样式.值得注意的是,CSS重置会从""中删除边距.
实际上,我认为这取决于您实际想要获得的帮助。这个问题有点模棱两可。如果您只想要相对于视口或相对于body元素的坐标,那么您的答案是正确的,但是在您想要元素的绝对位置的情况下,这无济于事(我想这是大多数人想要的) 。除非您删除“ -scrollLeft”和“ -scrollTop”位,否则喵的答案也不会给您任何帮助。

2> meouw..:

这些库会花费一些时间来获得元素的准确偏移量.
这是一个简单的功能,可以在我尝试的每种情况下完成工作.

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; 


更改:el = el.parentNode to:el = el.offsetParent; 它现在似乎适用于嵌套的iframe ...我在想这是你的意图吗?
这个解决方案不完整.尝试在div上放一个粗边框并将其嵌套几次.在任何版本的Firefox(2-5)中,它都会受到边框宽度的影响(即使在标准兼容模式下).
是不是有更清洁的方法,像el.totalOffsetLeft和totalOffsetTop函数?jQuery肯定有这个选项,但遗憾的是没有官方方法,我们需要等待DOM4吗?我正在构建一个HTML5画布应用程序,所以我认为最好的解决方案是在iframe中插入canvas元素,这样当我们点击元素时,我可以获得clientX和clientY的真实坐标.
这不适用于转换后的元素.

3> Adam Grant..:

这对我有用(从最高投票答案修改):

function getOffset(el) {
  const rect = el.getBoundingClientRect();
  return {
    left: rect.left + window.scrollX,
    top: rect.top + window.scrollY
  };
}

使用这个我们可以打电话

getOffset(element).left

要么

getOffset(element).top


也许它不是胜利者,因为它与Andy E的解决方案相同,但在旧浏览器`left:rect.left + window.scrollX +(rect.width / 2),top:rect.top + window.scrollY +(rect.height / 2)`将返回元素的中间位置

4> Amjad K..:

如果你想只在javascript中完成它.比这里有一个衬里.它的简单易于使用getBoundingClientRect()

window.scrollX + document.querySelector('#elementId').getBoundingClientRect().left // X

window.scrollY + document.querySelector('#elementId').getBoundingClientRect().top // Y


5> AnthonyWJone..:

大多数浏览器上的HTML元素都有: -

offsetLeft
offsetTop

这些指定了元素相对于具有布局的最近父元素的位置.通常可以通过offsetParent属性访问此父级.

IE和FF3都有

clientLeft
clientTop

这些属性不太常见,它们使用其父客户区指定元素位置(填充区域是客户区域的一部分,但边界和边距不是).



6> 小智..:

如果页面包含 - 至少 - 任何"DIV",则由meouw给出的函数会抛出超出当前页面限制的"Y"值.为了找到确切的位置,您需要同时处理offsetParent和parentNode.

尝试下面给出的代码(检查FF2):

var getAbsPosition = function(el){
    var el2 = el;
    var curtop = 0;
    var curleft = 0;
    if (document.getElementById || document.all) {
        do  {
            curleft += el.offsetLeft-el.scrollLeft;
            curtop += el.offsetTop-el.scrollTop;
            el = el.offsetParent;
            el2 = el2.parentNode;
            while (el2 != el) {
                curleft -= el2.scrollLeft;
                curtop -= el2.scrollTop;
                el2 = el2.parentNode;
            }
        } while (el.offsetParent);

    } else if (document.layers) {
        curtop += el.y;
        curleft += el.x;
    }
    return [curtop, curleft];
};



7> ThinkingStif..:

您可以添加两个属性以Element.prototype获取任何元素的顶部/左侧.

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 );
    }
} );

这被称为:

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

这里的比较结果以jQuery的演示offset().top.left:http://jsfiddle.net/ThinkingStiff/3G7EZ/


修改`Element.prototype`通常被认为是一个坏主意*.这导致很难维护代码.此外,此代码不考虑滚动.

8> Abdul Rahim ..:

要有效地检索相对于页面的位置,而不使用递归函数:(也包括IE)

var element = document.getElementById('elementId'); //replace elementId with your element's Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
                document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?                   
                 document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;



9> Alireza..:

这样的事情,通过传递元素的ID,它将返回左侧或顶部,我们也可以组合它们:

1)找到左边

function findLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.left + window.scrollX;
} //call it like findLeft('#header');

2)找到顶部

function findTop(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.top + window.scrollY;
} //call it like findTop('#header');

3)找到左边和顶部

function findTopLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return {top: rec.top + window.scrollY, left: rec.left + window.scrollX};
} //call it like findTopLeft('#header');



10> Shalom Craim..:

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

原型

jQuery的

MooTools的

YUI(雅虎)

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


所以你应该只为这个简单的任务使用庞大的库?不必要.我讨厌每次我想用js做一些事情,我都会得到这些jQuery解决方案.jQuery不是JS!
@scraimer:jQuery和YUI是**NOT frameworks**!!! 这些是**库**!这是不一样的.引用http://jquery.com/:_"jQuery是一个快速,小巧,功能丰富的JavaScript**库**."_引用http://yuilibrary.com/(你可以看到"魔术"一词在URL中...):_"YUI是一个免费的,开源的JavaScript和CSS**库**,用于构建丰富的交互式Web应用程序."_
@NickManning它不是一种新语言,它是DOM的抽象层,它消除了必须直接在代码中编写兼容性和性能变通方法.如果你不使用jQuery,你应该使用某种类型的抽象层.
@Costa他们都使用这些功能,虽然这是一个不断发展的领域,因为不同的浏览器与规范不同.这么多代码都涉及"修复"出错的事情.你真的应该看一下源代码.

11> akauppi..:

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



12> James Carlyl..:

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

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

getAbsoluteOffsetFromGivenElement - 返回相对于给定元素的绝对位置(relativeEl).请注意,给定元素必须包含元素el,否则其行为与getAbsoluteOffsetFromBody相同.如果您有两个元素包含在另一个(已知)元素(可选择在节点树中的几个节点)并希望使它们位于相同位置,则此选项非常有用.

getAbsoluteOffsetFromRelative - 返回相对于第一个父元素的绝对位置,其位置为: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中至少有一段有问题的代码,假设浏览器的行为应该没问题,但还没有测试其余的.



13> John_..:

如果使用jQuery,维度插件非常好,并允许您准确指定您想要的.

例如

相对位置,绝对位置,无填充的绝对位置,带衬垫......

它继续,让我们说你可以做很多事情.

此外,使用jQuery的好处是它的文件很轻,易于使用,之后如果没有它,你就不会再回到JavaScript了.



14> Adam Boostan..:

如果您使用的是jQuery,这可能是一个简单的解决方案:




15> Ron Reiter..:

这是我设法创建的最好的代码(也可以在iframe中工作,与jQuery的offset()不同).似乎webkit有一些不同的行为.

根据meouw的评论:

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 };
}


$ .browser在最新版本的jQuery中不再可用

16> KingRider..:

小与小的区别

function getPosition( 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 };
}

查看示例坐标:http: //javascript.info/tutorial/coordinates



17> James Montag..:

我发现最干净的方法是jQuery使用的技术的简化版本offset.与其他一些答案类似,它始于getBoundingClientRect; 然后使用windowdocumentElement调整滚动位置以及边距body(通常是默认值).

var rect = el.getBoundingClientRect();
var docEl = document.documentElement;

var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;

var els = document.getElementsByTagName("div");
var docEl = document.documentElement;

for (var i = 0; i < els.length; i++) {

  var rect = els[i].getBoundingClientRect();

  var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
  var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;

  els[i].innerHTML = "" + rectLeft + ", " + rectTop + "";
}
div {
  width: 100px;
  height: 100px;
  background-color: red;
  border: 1px solid black;
}
#rel {
  position: relative;
  left: 10px;
  top: 10px;
}
#abs {
  position: absolute;
  top: 250px;
  left: 250px;
}


18> Bojan Ksenem..:

我是这样做的,因此它与旧浏览器交叉兼容.

// 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;
    }

有关JavaScript中坐标的更多信息,请访问:http://javascript.info/tutorial/coordinates

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有