检索HTML元素相对于浏览器窗口的位置(X,Y)


1562

我想知道如何相对于浏览器窗口获取HTML元素(例如imgdiv在JavaScript中)的X和Y位置。


134
相对于什么?
AnthonyWJones

4
我一直在使用这7行代码,这些代码在所有浏览器中均能正常运行,但在ie5、6、7中存在差异(我不记得有任何问题……可能是文档类型)…… quirksmode.org/ js/findpos 。 html和我已经使用了很多年了。可能有人可以指出缺陷(如果有)。
Jayapal Chandran 2015年

98
@AnthonyWJones,我想您需要花哨的乐趣,但是很明显,因为在未指定的情况下,OP通常是最普通的情况,或者是浏览器的窗口坐标。
2015年

7
@Mote,不,不是很明显。抛开推论,主观性和错误公理。它可以相对于视口或页面顶部(也称为document.documentElement)。
安德烈·菲盖瑞多

15
默认为最一般的不是推论,而是逻辑上的进展,因此它是相对于窗口的,否则“ top of page”可能就是您所说的术语。在博弈论中,它被编纂为称为舒林点的概念。确保指定不代表最一般情况的时间。
微粒

Answers:


1792

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

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

Internet Explorer自从您很可能就一直在支持此功能,并且最终在CSSOM Views中对其进行了标准化。其他所有浏览器在很久以前就采用了它。

一些浏览器还返回height和width属性,尽管这是非标准的。如果您担心与旧版浏览器的兼容性,请查看此答案的修订版以实现优化的降级实现。

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

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

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

143
一个关于JS很有趣的文章坐标。这篇文章在SO上无处提及,应该..
e2-e4

6
不起作用...由于正文中有8px的空白,因此垂直和水平方向都是8像素。Meouw的解决方案效果很好。如果您愿意,我可以做一个小测试来证明问题所在。
CpnCrunch

3
实际上,我认为这取决于您实际想要获得的帮助。这个问题有点模棱两可。如果您只想要相对于视口或相对于body元素的坐标,则您的答案是正确的,但是在您想要元素的绝对位置的情况下,这对您没有帮助(我想这是大多数人想要的) 。除非您删除了“ -scrollLeft”和“ -scrollTop”位,否则喵的答案也不会给您任何帮助。
CpnCrunch 2014年

4
@CpnCrunch:我明白你的意思了;我没有意识到您是在指我回答的后半部分。当主体具有边距时,其边界框将在每个相应侧偏移该数量的像素。在这种情况下,还必须从主体坐标中减去计算出的边距样式。值得注意的是,CSS重置会从中删除边距<body>
安迪E

3
element.getBoundingClientRect().top如果position: fixediOS(iPhone 8)中的某个元素包含焦点输入元素并且虚拟键盘已经向上滑动,则不会返回正确的顶部偏移。例如,如果距窗口顶部的实际偏移量为200px,则它将报告为420px,其中220px是虚拟键盘的高度。如果您设置元素的position: absolute位置并将其放置在与固定位置相同的位置,那么您将获得正确的200px。我不知道解决方案。
贾尼斯·埃默里斯(JānisElmeris)'18年

327

库需要一定的长度才能获得元素的准确偏移量。
这是一个简单的函数,可以在我尝试过的所有情况下都能完成工作。

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; 

14
将el = el.parentNode更改为:el = el.offsetParent; 并且现在似乎适用于嵌套iframe ...我在想这就是您的意图吗?
亚当

4
该解决方案是不完整的。尝试在div上放置一个粗边框并将其嵌套几次。在任何版本的Firefox(2-5)中,其边框宽度都会关闭(即使在标准合规性模式下)。
ck_

3
还有没有更干净的方法,例如el.totalOffsetLeft和totalOffsetTop函数?jQuery当然具有此选项,但遗憾的是没有为此的正式方法,我们需要等待DOM4吗?我正在构建HTML5 canvas应用程序,所以我认为最好的解决方案是在iframe中插入canvas元素,这样当我们单击element时,我可以使用clientX和clientY获得真实的坐标。
baptx 2012年

1
那么,@ Adam和meouw,您是说第一个代码块是错误的吗?那为什么不将其全部删除呢?(多年来,这个问题已经吸引了很多观众;如果错了,可能会删除这些内容?)
Arjan 2012年

2
@baptx:我知道这是一个较晚的答复,但是我没有很快看到您的评论。请参阅下面的答案,以获得更符合标准的替代方法-甚至不需要真正的后备代码,因为浏览器已经支持了很长时间。
Andy E

242

这为我工作(从最高投票答案修改):

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

使用这个我们可以打电话

getOffset(element).left

要么

getOffset(element).top

1
只有将元素放置在div使用css居中的元素时,此解决方案才对我有效top:50%, left:50%; transform:translate(-50%, -50%);。同意@ScottBiggs的问题。逻辑上是寻求简单性。
nelek 2015年

3
也许它不是赢家,其原因与Andy E的解决方案相同,但不适用于旧的浏览器<IE9
niltoid

getBoundingClientRect导致我的性能图表中的大量重绘峰值
frumbert

1
你应该定义rect使用varletconst。否则,将其定义为window.rect
hev1

2
left: rect.left + window.scrollX + (rect.width / 2), top: rect.top + window.scrollY + (rect.height / 2)将返回元素的中间位置
Abhishake

94

如果你想完成它只是在javascript,这里有一些一个衬垫 使用getBoundingClientRect()

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

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

第一行将offsetTop相对于文档返回“ Y”。第二行将返回offsetLeft相对于文档的X。

getBoundingClientRect() 是一个javascript函数,它返回元素相对于窗口视口的位置。


2
这应该是解决方案。这里没有长代码bs,它可以理解并且非常准确!
E Alexis MT

2
如果该元素在可滚动元素之内怎么办?唯一的方法是对所有父元素的offsetTop求和,就像其他答案所建议的那样
Dmitri Pisarev

正如德米特里(Dmitri)所说,这是不正确的,而且存在很大缺陷。它应该没有像它一样多的赞成票。它也将始终位于可滚动元素中,因为文档本身可以滚动。换句话说,除非整个文档都适合视口,否则如果用户完全滚动了主窗口,它将始终是不正确的。
列夫

46

大多数浏览器上的HTML元素将具有:

offsetLeft
offsetTop

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

IE和FF3有

clientLeft
clientTop

这些属性不太常见,它们在其父级客户区中指定元素位置(填充区是客户区的一部分,而边界和边距则不是)。


36

如果页面至少包含“ 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];
};

1
与使用FF 24.4的其他解决方案一样,当边框宽度作为定位布局的一部分存在时,上述代码也不起作用。
2014年

你是救生员。我现在正在研究一些非常深的GWT错误,并将其抛出JSNI方法可以解决我所有的问题!
Will Byrne 2015年

35

您可以添加两个属性以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和进行比较的演示.lefthttp : //jsfiddle.net/ThinkingStiff/3G7EZ/


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

23

在不使用递归功能的情况下,有效地检索相对于页面的位置:(还包括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;

包括所有重要的scrollTop / scrollLeft可使此答案更正确。
scunliffe 2014年

19

这样的事情怎么样,通过传递元素的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');

16

使用JavaScript框架可能会更好地为您提供服务,该框架具有以与浏览器无关的方式返回此类信息(甚至更多!)的功能。这里有一些:

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


2
@Costa尽管这是一个不断发展的领域,但它们都使用那些功能,因为不同的浏览器对规范的遵循方式不同。如此多的代码处理“修复”出问题的东西。您确实应该查看源代码。
Shalom Craimer

18
@scraimer:jQuery和YUI 不是框架!这些是图书馆!这是不一样的。引用jquery.com “jQuery是一个快速,小巧,功能丰富的JavaScript 。” 引用yuilibrary.com(您也可以在URL中看到“魔术”一词...):“ YUI是一个免费的开源JavaScript和CSS 库,用于构建丰富的交互式Web应用程序。”
Sk8erPeter

29
因此,您应该仅将大型库用于此简单任务吗?没有必要。我讨厌每次我想用js做某事时,我都会得到这些jQuery解决方案。jQuery不是JS!
Opptatt Jobber

1
@OpptattJobber我同意... jQuery不是javascript。它依赖Javascript,但完全是另一种编程语言。
尼克·曼宁2014年

5
@NickManning它不是一种新语言,它是DOM的抽象层,消除了直接在代码中编写兼容性和性能变通办法的麻烦。如果您不使用jQuery,则无论如何都应该使用某种类型的抽象层。
ginman 2014年

15

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


由于某些原因,与其他浏览器相比,它在IE中无法提供相同的结果。我认为IE中的位置是相对于窗口的,因此,如果滚动,则与其他人相比,IE中的结果将有所不同
Abdul Rahim Haddad 2013年

1
至少在Android Chrome中,offset()被缩放所迷惑,因此它没有用。stackoverflow.com/a/11396681/1691517显示了可缩放的方式。
TimoKähkönen'15

10

我已经采用@meouw的答案,将其添加到允许边框的clientLeft中,然后创建了三个版本:

getAbsoluteOffsetFromBody-与@meouw相似,它获取相对于文档正文或html元素的绝对位置(取决于怪癖模式)

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中至少有一个可疑的代码,假设浏览器的行为正常,应该可以,但完全没有测试其余部分。


有趣的是...但是在Edge上,当我滚动时getAbsoluteOffsetFromBody(element).top返回一个不同的值,在Chrome中,滚动时它保持一致。似乎Edge正在调整滚动位置。当元素滚动到视图之外时,我得到一个负值。
诺曼

getAbsoluteOffsetFromRelative让我很开心,我不得不在没有引导程序Javascript的情况下重现引导程序工具提示,这对我有很大帮助。
Nolyurn

万一Meouw更改了用户名,请链接到答案:stackoverflow.com/a/442474/3654837。(我不想碰到这个旧线程,所以,我发表评论了)
Mukyuu

8

如果使用jQuery,则Dimensions插件非常出色,可让您准确指定所需的内容。

例如

相对位置,绝对位置,不带填充的绝对位置,带填充...

它还在继续,让我们说您可以做很多事情。

加上使用jQuery的好处是它的文件大小轻巧且易于使用,如果没有它,您将不会再使用JavaScript。


8

这是我设法创建的最佳代码(与jQuery的offset()不同,它也可以在iframe中使用)。似乎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 };
}

请注意,您需要jQuery使用$.browser.webkit; 您需要试用navigator.userAgent才能使用pure进行相同操作JavaScript
SP

2
$ .browser在最新版本的jQuery中不再可用
Gus 2014年

不幸的是,即使使用FF 24.4,当边框宽度作为定位布局的一部分存在时,上述代码也无法使用。
2014年

8

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

<script>
  var el = $("#element");
  var position = el.position();
  console.log( "left: " + position.left + ", top: " + position.top );
</script>

8

小与小的区别

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


不幸的是,这不适用于现代HTML文档中可能找到的所有元素。嵌入式<svg>元素,例如,没有offsetLeftoffsetTopoffsetParent性能。
乔纳森·尤尼斯

它只是DIV或者IMG,不是SVG。查看“查看示例坐标”?您会发现对象svg是位置调用getOffsetRect,尝试并依赖对象的工作。
KingRider

7

我发现的最干净的方法是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;


6

尽管很可能在这么多答案的最底端都看不到这一点,但此处的最佳解决方案对我而言并不起作用。
据我所知,其他答案都无济于事。

情况
在HTML5页面中,我有一个菜单,该菜单是标题中的nav元素(不是THE标题,而是另一个元素中的标题)。
我希望导航在用户滚动到顶部时停留在顶部,但是在此之前,页眉是绝对定位的(因此我可以将其稍微覆盖一下)。
上面的解决方案从未触发更改,因为.offsetTop不会更改,因为这是绝对定位的元素。此外,.scrollTop属性只是最上面的元素的顶部...也就是说0,并且始终为0。
我使用这两项进行的任何测试(与getBoundingClientRect结果相同)都不会告诉我导航栏的顶部是否曾经滚动到可见页面的顶部(再次,如控制台中所报告的那样,它们在滚动时仅保持相同的数字)发生了)。

解决
方案对我来说,解决方案是利用

window.visualViewport.pageTop

pageTop属性的值反映了屏幕的可视区域,因此允许我跟踪元素在可视区域边界上的引用。

也许无需多说,每当我要处理滚动时,我都希望使用此解决方案以编程方式响应被滚动元素的运动。
希望它可以帮助别人。
重要说明:这似乎目前在Chrome和Opera中有效,并且在Firefox(6-2018)中绝对不可用 ...直到Firefox支持visualViewport之前,我建议不要使用此方法,(并且我希望它们能尽快使用...这很有帮助。比其余的更有意义)。


更新:
只是有关此解决方案的说明。
虽然我仍然发现我发现的内容对于“ ...以编程方式响应所滚动元素的移动”的情况非常有价值。适用。对于我遇到的问题,更好的解决方案是使用CSS设置位置:粘性在元素上。使用sticky,您可以不使用javascript就将元素保留在顶部(注意:有时候,这不能像将元素更改为fixed那样有效,但是对于大多数使用sticky的方法可能会更好)

UPDATE01:
所以我意识到对于另一个页面,我有一个要求,我需要在一个稍微复杂的滚动设置(视差加上作为消息一部分滚动过去的元素)中检测元素的位置。我意识到在这种情况下,以下内容提供了我用来确定何时进行操作的值:

  let bodyElement = document.getElementsByTagName('body')[0];
  let elementToTrack = bodyElement.querySelector('.trackme');
  trackedObjPos = elementToTrack.getBoundingClientRect().top;
  if(trackedObjPos > 264)
  {
    bodyElement.style.cssText = '';
  }

希望这个答案现在更广泛地有用。


当您单击“ 活动”以对答案进行排序时,这很有可能位于众多答案的顶部
lucchi

@lucchi:D好吧,我想我可以删除@顶部的文本...虽然我又一次碰到了这一点,并且意识到我为自己的问题找到了更好的解决方案...尽管我的回答更多是注意更完整的答案。我怀疑我的要求可能不那么普遍,以至于其他答案对我不起作用?
MER

1
无论如何,我都很感谢您的回答,只是告诉您,任何愿意的人都会意识到您写了一些新东西。您并不孤单
。...– lucchi

5

我这样做是为了让它与旧的浏览器交叉兼容。

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


4

要获取元素的总偏移量,可以递归地汇总所有父偏移量:

function getParentOffsets(el): number {
if (el.offsetParent) {
    return el.offsetParent.offsetTop + getParentOffset(el.offsetParent);
} else {
    return 0;
}
}

使用此实用程序功能,dom元素的总顶部偏移为:

el.offsetTop + getParentOffsets(el);

3
/**
 *
 * @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;
}

感谢ThinkingStiff答案,这是它只是另一个版本。


2

我成功地使用了Andy E的解决方案来根据用户单击表行中的链接来定位bootstrap 2模态。该页面是Tapestry 5页面,下面的javascript被导入到Java页面类中。

javascript:

function setLinkPosition(clientId){
var bodyRect = document.body.getBoundingClientRect(),
elemRect = clientId.getBoundingClientRect(),
offset   = elemRect.top - bodyRect.top;
offset   = offset + 20;
$('#serviceLineModal').css("top", offset);

}

我的模态代码:

<div id="serviceLineModal" class="modal hide fade add-absolute-position" data-backdrop="static" 
 tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="top:50%;">
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
    <h3 id="myModalLabel">Modal header</h3>
</div>

<div class="modal-body">
    <t:zone t:id="modalZone" id="modalZone">
        <p>You selected service line number: ${serviceLineNumberSelected}</p>
    </t:zone>
</div>

<div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <!-- <button class="btn btn-primary">Save changes</button> -->
</div>

循环中的链接:

<t:loop source="servicesToDisplay" value="service" encoder="encoder">
<tr style="border-right: 1px solid black;">       
    <td style="white-space:nowrap;" class="add-padding-left-and-right no-border"> 
        <a t:type="eventLink" t:event="serviceLineNumberSelected" t:context="service.serviceLineNumber" 
            t:zone="pageZone" t:clientId="modalLink${service.serviceLineNumber}"
            onmouseover="setLinkPosition(this);">
            <i class="icon-chevron-down"></i> <!-- ${service.serviceLineNumber} -->
        </a>
    </td>

以及页面类中的Java代码:

void onServiceLineNumberSelected(String number){
    checkForNullSession();
    serviceLineNumberSelected = number;
    addOpenServiceLineDialogCommand();
    ajaxResponseRenderer.addRender(modalZone);
}

protected void addOpenServiceLineDialogCommand() {
    ajaxResponseRenderer.addCallback(new JavaScriptCallback() {
        @Override
        public void run(JavaScriptSupport javascriptSupport) {
            javascriptSupport.addScript("$('#serviceLineModal').modal('show');");
        }
    });
}

希望这对某人有帮助,这篇文章对您有所帮助。


这段js代码对我有帮助,我有一个使用多个占位符的旧Webforms应用程序,它会插入.aspx页面,但由于整个DOM树都是重整的,所以我不知道如何将其创建的弹出框的appendChild()插入视口与多个占位符和不正确的标记。我需要使用body.getBoundingClientRect()然后在定位中使用其顶部。谢谢。
布拉德·马丁

1

经过大量研究和测试,这似乎可行

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

参见http://jsbin.com/xuvovalifo/edit?html,js,输出


1

只是以为我也会把它扔在那里。
我无法在较旧的浏览器中对其进行测试,但是它可以在前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()};
};

0

由于不同的浏览器以不同的方式呈现边框,内边距,边距等。我编写了一个小函数来检索要精确定位的每个根元素中特定元素的顶部和左侧位置:

function getTop(root, offset) {
    var rootRect = root.getBoundingClientRect();
    var offsetRect = offset.getBoundingClientRect();
    return offsetRect.top - rootRect.top;
}

要获取左侧位置,您必须返回:

    return offsetRect.left - rootRect.left;

-1

获取div相对于左侧和顶部的位置

  var elm = $('#div_id');  //get the div
  var posY_top = elm.offset().top;  //get the position from top
  var posX_left = elm.offset().left; //get the position from left 

我投了反对票,因为右下角不是offset()的属性
MacroMan

@MacroMan,我尊重您的决定,但是我已经在文本中解释了“未对代码的底部和右侧进行测试”。另外,我将很快更新我的代码。
维沙尔

我认为这是el.offsetTopel.offsetLeft(任择议定书并没有说明什么jQuery的...我不知道为什么你的答案用了jQuery要么...)
mesqueeb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.