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


当前回答

我成功地使用Andy E的解决方案,根据用户单击的表行中的链接来定位引导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');");
        }
    });
}

希望这对某人有所帮助,这篇文章帮了大忙。

其他回答

更新:

递归方法(在我以前的答案中)创建了许多调用堆栈。在这种情况下,我们可以使用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的回答,这只是另一个版本。

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

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; 

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

原型jQuery框架YUI(雅虎)

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

这很简单,在JS中有两行:

var elem = document.getElementById("id");    
alert(elem.getBoundingClientRect());

虽然这很可能会在这么多答案的底部丢失,但这里的顶级解决方案并不适合我。据我所知,其他答案都没有帮助。情况:在HTML5页面中,我有一个菜单,它是页眉中的导航元素(不是页眉,而是另一个元素中的页眉)。我希望一旦用户滚动到顶部,导航就一直保持在顶部,但在此之前,标题是绝对定位的(所以我可以让它稍微覆盖一些其他内容)。上述解决方案从未触发过更改,因为.offsetTop不会更改,因为这是一个绝对定位的元素。此外,scrollTop属性只是最顶部元素的顶部。。。也就是说0并且总是0。我使用这两个(以及getBoundingClientRect结果)执行的任何测试都不会告诉我导航栏的顶部是否曾滚动到可查看页面的顶部(再次,正如控制台中所报告的那样,它们只是在滚动时保持相同的数字)。

解决方案我使用的解决方案

window.visualViewport.pageTop

pageTop属性的值反映了屏幕的可视部分,因此允许我跟踪元素相对于可视区域边界的位置。

也许没必要说,每当我处理滚动时,我都希望使用这个解决方案以编程方式响应正在滚动的元素的移动。希望它能帮助其他人。重要提示:这似乎在Chrome和Opera中有效,在Firefox(6-2018)中肯定不行。。。在Firefox支持visualViewport之前,我建议不要使用这种方法(我希望他们很快会使用……这比其他方法更有意义)。更新:请注意此解决方案。虽然我仍然发现我发现的对于“……以编程方式响应滚动元素的移动”的情况非常有用。我遇到的问题的更好解决方案是使用CSS在元素上设置位置:粘滞。使用sticky,您可以在不使用javascript的情况下让一个元素保持在顶部(注意:有时这不会像将元素更改为固定的那样有效,但对于大多数情况,sticky方法可能会更好)更新01:所以我意识到,对于不同的页面,我需要在一个稍微复杂的滚动设置中检测元素的位置(视差加上作为消息一部分滚动经过的元素)。在这种情况下,我意识到以下内容提供了我用来确定何时做某事的价值:

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

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